Al ejecutar scripts en bash, tengo que escribir ./
al principio:
$ ./manage.py syncdb
Si no lo hago, recibo un mensaje de error:
$ manage.py syncdb
-bash: manage.py: command not found
¿Cuál es la razón para esto? Pensé que .
era 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 ./
)
bash
shell
unix
command-line
Dan Abramov
fuente
fuente
Respuestas:
Porque en Unix, por lo general, el directorio actual no está en
$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 e ingresas al directorio de otro usuario y escribes en
sl
lugar dels
. Si el directorio actual está dentroPATH
, el shell intentará ejecutar elsl
programa en ese directorio (ya que no hay otrosl
programa). Esesl
programa puede ser malicioso.Funciona con
./
porque POSIX especifica que un nombre de comando que contiene un/
se utilizará directamente como nombre de archivo, suprimiendo una búsqueda en$PATH
. Podría haber utilizado la ruta completa para el mismo efecto exacto, pero./
es más corto y más fácil de escribir.EDITAR
Esa
sl
parte fue solo un ejemplo. Los directoriosPATH
se buscan secuencialmente y cuando se hace una coincidencia, se ejecuta ese programa. Entonces, dependiendo de cómo sePATH
vea, escribir un comando normal puede o no ser suficiente para ejecutar el programa en el directorio actual.fuente
ls
archivo ejecutable..\my.bat
etc. para ejecutarlosl
comando llamado locomotora de vapor, aunque no está disponible por defecto ;-)Cuando bash interpreta la línea de comando, busca comandos en las ubicaciones descritas en la variable de entorno
$PATH
. Para verlo escriba:Tendrás algunos caminos separados por dos puntos. Como verá, la ruta actual
.
generalmente no está en$PATH
. Entonces Bash no puede encontrar su comando si está en el directorio actual. Puede cambiarlo teniendo:Esta línea agrega el directorio actual
$PATH
para que pueda hacer:Es no se recomienda ya que tiene problema de seguridad, además de que puede tener comportamientos extraños, como
.
varía dependiendo del directorio que está en :)Evitar:
Como puede "enmascarar" algún comando estándar y abrir la puerta a la violación de seguridad :)
Solo mis dos centavos.
fuente
Su script, cuando esté en su directorio de inicio, no se encontrará cuando el shell mire el
$PATH
variable de entorno para encontrar su secuencia de comandos.El
./
dice 'busca en mi directorio actual mi script en lugar de mirar todos los directorios especificados en$PATH
'.fuente
Cuando incluye el '.' esencialmente está dando la "ruta completa" al script bash ejecutable, por lo que su shell no necesita verificar su variable PATH. Sin el '.' su shell se verá en su variable PATH (que puede ver ejecutando
echo $PATH
para ver si el comando que escribió se encuentra en alguna de las carpetas de su PATH. Si no lo hace (como es el caso con manage.py) lo dice no puedo encontrar el archivo. Se considera una mala práctica incluir el directorio actual en su RUTA, que se explica razonablemente bien aquí: http://www.faqs.org/faqs/unix-faq/faq/part2/section- 13.htmlfuente
En * nix, a diferencia de Windows, el directorio actual generalmente no está en su
$PATH
variable. Por lo tanto, el directorio actual no se busca al ejecutar comandos. No necesita./
ejecutar aplicaciones porque estas aplicaciones están en su $ PATH; lo más probable es que estén en/bin
o/usr/bin
.fuente
Esta pregunta ya tiene algunas respuestas increíbles, pero quería agregar eso, si su ejecutable está en la RUTA, y obtiene resultados muy diferentes cuando ejecuta
a los que obtienes si corres
(supongamos que se encuentra con mensajes de error con uno y no con el otro), entonces el problema podría ser que tiene dos versiones diferentes del ejecutable en su máquina: una en la ruta y la otra no.
Comprueba esto ejecutando
cual ejecutable
y
Solucionó mis problemas ... Tenía tres versiones del ejecutable, solo una de las cuales se compiló correctamente para el entorno.
fuente
Justificación de la
/
regla POSIX PATHLa regla se mencionó en: ¿Por qué necesita ./ (punto-barra) antes del ejecutable o el nombre del script para ejecutarlo en bash?pero me gustaría explicar por qué creo que es un buen diseño con más detalle.
Primero, una versión completa explícita de la regla es:
/
(por ejemplo./someprog
,/bin/someprog
,./bin/someprog
): se usa CWD y PATH no/
(psomeprog
. ej. ): se utiliza PATH y CWD noAhora, supongamos que se ejecuta:
buscaría:
Entonces, si querías huir
/bin/someprog
de tu distribución, y lo hiciste:a veces funcionaría, pero otras fallaría, porque podría estar en un directorio que contiene otro no relacionado
someprog
programa .Por lo tanto, pronto aprenderá que esto no es confiable, y terminaría siempre usando rutas absolutas cuando quiera usar PATH, por lo tanto, anulará el propósito de PATH.
Esta es también la razón por la que tener rutas relativas en su RUTA es una muy mala idea. Te estoy mirando
node_modules/bin
.Por el contrario, supongamos que se ejecuta:
Buscaría:
Luego, si acaba de descargar un script
someprog
de un repositorio de git y desea ejecutarlo desde CWD, nunca estaría seguro de que este es el programa real que se ejecutaría, porque tal vez su distribución tiene un:que está en su RUTA de algún paquete que instaló después de beber demasiado después de Navidad el año pasado.
Por lo tanto, una vez más, se vería obligado a ejecutar siempre scripts locales en relación con CWD con rutas completas para saber lo que está ejecutando:
lo cual sería extremadamente molesto también.
Otra regla que podría verse tentado a inventar sería:
pero una vez más, esto obliga a los usuarios a usar siempre rutas absolutas para scripts que no son de RUTA con
"$(pwd)/someprog"
.La
/
regla de búsqueda de ruta ofrece una solución fácil de recordar para el problema:PATH
PATH
lo que hace que sea muy fácil saber siempre lo que está ejecutando, confiando en el hecho de que los archivos en el directorio actual se pueden expresar como
./somefile
osomefile
, por lo que le da un significado especial a uno de ellos.A veces, es un poco molesto que no se puede buscar en
some/prog
relaciónPATH
, pero no veo una solución más sensata para esto.fuente
Cuando el script no está en la ruta, se requiere que lo haga. Para obtener más información, lea http://www.tldp.org/LDP/Bash-Beginners-Guide/html/sect_02_01.html
fuente
Todo tiene una gran respuesta a la pregunta, y sí, esto solo es aplicable cuando se ejecuta en el directorio actual, a menos que incluya la ruta absoluta. Ver mis muestras a continuación.
Además, el (punto-barra) tenía sentido para mí cuando tengo el comando en la carpeta secundaria tmp2 (/ tmp / tmp2) y usa (doble barra-punto).
MUESTRA:
fuente