¿Por qué necesita ./ (punto-barra) antes del ejecutable o del nombre del script para ejecutarlo en bash?
Cuando ejecuto scripts en bash, tengo que escribir ./
al principio:
$ ./manage.py syncdb
Si no lo hago, aparece un mensaje de error:
$ manage.py syncdb
-bash: manage.py: command not found
¿Cuál es la razón para esto? Pensé .
que es un alias para la carpeta actual y, por lo tanto, estas dos llamadas deberían ser equivalentes.
Tampoco entiendo por qué no lo necesito ./
cuando ejecuto aplicaciones, como:
user:/home/user$ cd /usr/bin
user:/usr/bin$ git
(que corre sin ./
)
Porque en Unix, normalmente, el directorio actual no está en formato $PATH
.
Cuando escribe un comando, el shell busca una lista de directorios, según lo especificado por la PATH
variable. El directorio actual no está en esa lista.
La razón para no tener el directorio actual en esa lista es la seguridad.
Digamos que eres root, vas al directorio de otro usuario y escribes sl
en lugar de ls
. Si el directorio actual está en PATH
, el shell intentará ejecutar el sl
programa en ese directorio (ya que no hay ningún otro sl
programa). Ese sl
programa podría ser malicioso.
Funciona ./
porque POSIX especifica que un nombre de comando que contenga a /
se usará directamente como nombre de archivo, suprimiendo una búsqueda en $PATH
. Podrías haber utilizado la ruta completa para obtener exactamente el mismo efecto, pero ./
es más corta y más fácil de escribir.
EDITAR
Esa sl
parte fue sólo un ejemplo. Los directorios PATH
se buscan secuencialmente y cuando se encuentra una coincidencia, se ejecuta ese programa. Entonces, dependiendo de cómo PATH
se vea, escribir un comando normal puede o no ser suficiente para ejecutar el programa en el directorio actual.
Cuando bash interpreta la línea de comando, busca comandos en las ubicaciones descritas en la variable de entorno $PATH
. Para verlo escribe:
echo $PATH
Tendrás algunos caminos separados por dos puntos. Como verá, la ruta actual .
generalmente no está en formato $PATH
. Entonces Bash no puede encontrar su comando si está en el directorio actual. Puedes cambiarlo teniendo:
PATH=$PATH:.
Esta línea agrega el directorio actual $PATH
para que pueda hacer:
manage.py syncdb
No se recomienda ya que tiene problemas de seguridad y además puede tener comportamientos extraños, ya que .
varía según el directorio en el que se encuentre :)
Evitar:
PATH=.:$PATH
Como puedes "enmascarar" algún comando estándar y abrir la puerta a una violación de seguridad :)
Sólo mis dos centavos.
Su secuencia de comandos, cuando esté en su directorio de inicio, no se encontrará cuando el shell busque la $PATH
variable de entorno para encontrar su secuencia de comandos.
Dice ./
'busque mi script en el directorio actual en lugar de mirar todos los directorios especificados en $PATH
'.