Al ejecutar un programa en C a.out
, usando el terminal de Ubuntu, ¿por qué siempre necesito escribir ./
antes a.out
, en lugar de solo escribir a.out
? ¿Hay alguna solución para esto?
Al ejecutar un programa en C a.out
, usando el terminal de Ubuntu, ¿por qué siempre necesito escribir ./
antes a.out
, en lugar de solo escribir a.out
? ¿Hay alguna solución para esto?
Respuestas:
Cuando escribe el nombre de un programa como a.out
el sistema busca el archivo en su RUTA. En mi sistema, PATH está configurado en
/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
El tuyo es probablemente similar. Para verificar, ingrese echo $PATH
en una terminal.
El sistema mira a través de estos directorios en el orden dado y si no puede encontrar el programa produce un command not found
error.
Anteponer el comando con ./
efectivamente dice "olvídate de la RUTA, quiero que mires solo en el directorio actual".
Del mismo modo, puede indicarle al sistema que busque solo en otra ubicación específica anteponiendo el comando con una ruta relativa o absoluta como:
../
significa en el directorio principal, por ejemplo, ../hello
busque hola en el directorio principal.
./Debug/hello
: "buscar hello
en el subdirectorio Debug de mi directorio actual".
o /bin/ls
: "buscar ls
en el directorio /bin
"
De manera predeterminada, el directorio actual no está en la ruta porque se considera un riesgo de seguridad. Ver por qué es. no en la ruta por defecto? en Superusuario por qué.
Es posible agregar el directorio actual a su RUTA, pero por las razones dadas en la pregunta vinculada, no lo recomendaría.
.
a su PATH
(como sugieren las otras 2 respuestas actualmente) debido al riesgo de seguridad mencionado en esta respuesta.
.
aquí, puede usar una ruta completa o relativa a un ejecutable, por ejemplo, /home/user/foo/a.out
o./build/a.out
.
es especial porque significa "mi directorio actual" y podría ser cualquier directorio en el que el usuario se encuentre con privilegios de lectura y ejecución. Esto es potencialmente más peligroso que agregar una ruta específica totalmente calificada.
.
no tiene un estado especial, es solo una ruta que podría comenzar con /
y ./blah
funcionaría tan bien con cat
o grep
como un indicador de bash.
La razón de esto es simple.
Suponga que tiene un comando con el mismo nombre que una aplicación en el directorio actual. Luego, ejecutar el comando en el shell invocaría su aplicación en lugar del comando incorporado. Esto sería una preocupación de seguridad si nada más.
Al requerir ./
que se use en frente, el shell sabe que desea ejecutar la aplicación con el nombre de pila y no un comando incorporado con ese nombre.
./
ejecuta archivos que no están en su $PATH
, más bien ejecuta el archivo en el directorio actual (u otra vía ./home/stefano/script.sh
). Ahora, PATH es una variable de entorno que contiene todos los lugares donde bash puede buscar programas ejecutables, sin tener la ruta completa (absoluta) hacia ellos.
Esta separación es necesaria para evitar ejecutar el archivo incorrecto. Es decir, si tiene un archivo llamado ls
en su directorio de inicio, no estar en su RUTA evitará que bash lo confunda con lo real ls
. La variable PATH también define el orden de búsqueda:
exec
llamada al sistema (un método especial del Kernel, cómo se inician los programas), el sistema busca el archivo revisando cada uno de los directorios en su RUTA. Una vez que se ha encontrado el programa, incluso si está en varios directorios, la búsqueda se interrumpe y se ejecuta el primero encontrado.Para ejecutar un archivo, deberá establecer el bit ejecutable en los permisos:
Como ya estás en la línea de comando, puedes escribir chmod +x finename
.
O puede establecer los permisos haciendo clic derecho en el archivo y seleccionando Propiedades :
Ahora puede copiar el archivo a cualquiera de los directorios en PATH, para ver cuáles están allí, y están configurados por usuario, tipo echo $PATH
.
stefano@3000-G530:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
Si crea un archivo ejecutable cat
, y lo mueve /usr/local/sbin
, se ejecuta en lugar del correcto cat
, que reside en /bin
. Puede averiguar dónde están sus archivos utilizando type cat
y whereis cat
.
gcc
, lo que establece automáticamente el bit de ejecución.
./
antes de ejecutar un programa?En el terminal, cada vez que escriba el nombre de una aplicación, digamos gedit
, el terminal buscará en algunos directorios (predefinidos) que contienen aplicaciones (los binarios de las aplicaciones). Los nombres de estos directorios están contenidos en una variable llamada PATH
. Puede ver lo que hay en esta variable ejecutando echo $PATH
. ¿Ves esos directorios separados por :
? Esos son los directorios que el terminal será ir a buscar adentro, si usted sólo tiene que escribir gedit
, nautilus
o a.out
. Como puede ver, la ruta de su a.out
programa no está allí. Cuando lo hace ./a.out
, le está diciendo a la terminal que "mire en el directorio actual, y ejecute a.out
, y no vaya a buscar PATH
.
Si no desea escribir ./
todo el tiempo, deberá agregar a.out
el directorio $PATH
. En las siguientes instrucciones, supondré que la ruta a.out
es /path/to/programs/
, pero debe cambiarla a su ruta real.
Simplemente agregue la siguiente línea al final del archivo ~/.pam_environment
:
PATH DEFAULT=${PATH}:/path/to/programs
Cerrar la sesión y volver a iniciarla. Ahora va a ser capaz de ejecutar a.out
sin ./
desde cualquier directorio.
Si tiene otros programas en otros directorios, puede agregarlos a la línea anterior. Sin embargo, aconsejaría tener un directorio llamado "myPrograms", por ejemplo, y poner todos sus programas debajo.
Nota: cambie
userName
a su nombre de usuario real de Ubuntu.
¿Qué pasa si tiene otros programas que desea ejecutar? ¿Y están todos en carpetas diferentes? Bueno, una solución "más organizada" sería crear una carpeta llamada bin
bajo su directorio de Inicio y agregar enlaces simbólicos (atajos) debajo de esa carpeta. Así es cómo:
mkdir /home/userName/bin
bin
debajo de su directorio de inicio.ln -s /path/to/programs/a.out /home/userName/bin
a.out
programa en bin
.Cerrar la sesión y volver a iniciarla. Ahora va a ser capaz de ejecutar a.out
sin ./
desde cualquier directorio.
Ahora, cada vez que tenga otro programa en cualquier otro lugar, digamos que el programa b.in
en su Escritorio, todo lo que necesita hacer es: ln -s /home/userName/Desktop/b.in /home/userName/bin
y luego podrá ejecutarlo sin él ./
también.
Nota: gracias al comentario de @ Joe , cuando haces copias de seguridad, los enlaces simbólicos deben manejarse especialmente. Por defecto,
rsync
no los procesa en absoluto, por lo que cuando restaura, no están allí.
Como George señaló en su respuesta, esto le ayuda a notar que está ejecutando un archivo en el directorio de trabajo actual ( pwd
).
Recuerdo haberle hecho esta pregunta a mi superior hace mucho tiempo, dijo que debería agregar .
a mi camino para que cuando lo haga, a.out
se vea en el directorio actual y lo ejecute. En este caso no tengo que hacer ./a.out
.
Pero, personalmente, recomendaría no hacerlo. Nunca me sucedió, pero si estás en un directorio de red alienígena o algo así y ls
existe un archivo ejecutable malicioso llamado allí, entonces tener .
en tu camino es una muy mala idea. No es que te encuentres con este problema muy a menudo, solo digo.
.
a $PATH
. Una idea muy peligrosa.
Además de otras respuestas, aquí la parte esencial a partir de la man bash
cual se explica eso bien:
EJECUCIÓN DE MANDO Después de que un comando se haya dividido en palabras, si resulta en un simple comando y una lista opcional de argumentos, las siguientes acciones son tomado. Si el nombre del comando no contiene barras, el shell intenta localizar eso. Si existe una función de shell con ese nombre, esa función es invocado como se describe anteriormente en FUNCIONES. Si el nombre no coincide con un función, el shell lo busca en la lista de shell incorporados. Si se encuentra una coincidencia, se invoca esa construcción. Si el nombre no es una función de shell ni una función incorporada, y no contiene barras, bash busca en cada elemento de la RUTA un directorio con‐ contener un archivo ejecutable con ese nombre.
Un './' tiene sentido cuando ejecuta un programa que es conocido por usted y específico, por ejemplo, el suyo propio. Este programa debe estar presente en su directorio actual. Un './' no tiene sentido cuando ejecuta un comando estándar que está en algún lugar de $ PATH. Un comando "which command-to-run" le dice dónde está el comando-to-run en $ PATH.
$ gcc hello.c -o /path/to/someplace/hello
producirá un ejecutable en alguna ubicación. Si esa ubicación está en su camino, podrá ejecutar el archivo. Puede escribir esto si desea crear una etiqueta para la acción "compile este código fuente usando el gcc y coloque un ejecutable en alguna ubicación que esté en su ruta"
Le sugiero que cree un nuevo directorio llamado "testbin" o algo por el estilo y lo coloque en su ruta para mantener limpios sus directorios de ruta existentes.
./
elimina la búsqueda innecesaria de una ruta. ./
forzar a buscar solo en el directorio actual. Si no damos ./
a continuación, se buscará varias camino trazado en el sistema como /usr/bin
, /usr/sbin/
, etc.
"./" significa que desea ejecutar un archivo en el directorio actual, es un acceso directo para escribir la ruta completa, por ejemplo:
[root@server ~]#/path/to/file/file.pl
es igual que:
[root@server file]#./file.pl
en el ejemplo anterior, recorrió el directorio y sus sup-directorios hasta la ubicación del archivo y utilizó "./" para ejecutar el archivo en el directorio actual.
el anterior " [root @ server ~] # / path / to / file / file.pl " también ejecutará el archivo si va a "cd" su camino a la ubicación del archivo.
Es muy simple y tiene muchos usos.
/usr/bin
. Por ejemplo, Python 2.7, Python 2.6 está instalado pero / usr / bin / python -> python2.7 / usr / local / bin / python -> python2.6Si está en la ruta /usr/local/bin
y ejecuta Python, siempre ejecutará Python 2.7. La especificación .
tomará el ejecutable de la carpeta actual.
.
- siempre representa ejecutar desde el directorio actual. Y ..
siempre significa que se ejecuta desde el directorio anterior.