2011-06-13 5 views
201

Al ejecutar scripts en bash, tengo que escribir ./ en el principio:¿Por qué necesita ./ (dot-slash) antes del ejecutable o el nombre del script para ejecutarlo en bash?

$ ./manage.py syncdb 

Si no lo hago, me sale un mensaje de error:

$ manage.py syncdb 
-bash: manage.py: command not found 

¿Cuál es la razón de esto? Pensé que . es un alias para la carpeta actual, y por lo tanto estas dos llamadas deberían ser equivalentes.

Asimismo, no entiendo por qué no necesito ./ cuando se ejecutan aplicaciones, tales como:

user:/home/user$ cd /usr/bin 
user:/usr/bin$ git 

(que funciona sin ./)

+1

Este es el mejor documento sobre el asunto que he encontrado hasta ahora: http://www.linfo.org/dot_slash.html – odigity

Respuesta

209

Debido a que en Unix, por lo general, el directorio actual no está en $PATH.

Cuando escribe un comando, el shell busca una lista de directorios, como se especifica en la variable PATH. 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 y ve al directorio de otro usuario y escribe sl en lugar de ls. Si el directorio actual está en PATH, el shell intentará ejecutar el programa sl en ese directorio (ya que no hay otro programa sl). Ese programa sl podría ser malicioso.

funciona con ./ porque POSIX specifies que un nombre de comando que contiene un / se utilizará como nombre de archivo directamente, 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

Eso sl parte era sólo un ejemplo. Los directorios en PATH se buscan secuencialmente y cuando se realiza una coincidencia, ese programa se ejecuta. Entonces, dependiendo de cómo se vea PATH, escribir un comando normal puede o no ser suficiente para ejecutar el programa en el directorio actual.

+34

No necesita escribir mal nada. El usuario puede haber descargado un paquete malicioso que contiene un ejecutable 'ls'. – Juliano

+0

¿Esto significa que '.' no es solo un alias para la carpeta actual, sino que se 'expande' a toda la ruta? No lo sabía, gracias .. –

+9

Solo una nota para todos los que dicen que esto solo está en Unix y no en Windows, esto es lo mismo en Powershell: tienes que hacer '. \ My.bat' etc. para ejecutar – manojlds

27

Su secuencia de comandos, cuando se encuentre en su directorio de inicio, no se encontrará cuando el shell consulte la variable de entorno $PATH para encontrar su secuencia de comandos.

./ dice 'busque en el directorio actual de mi script en lugar de mirar todos los directorios especificados en $PATH'.

1

Cuando la secuencia de comandos no está en la Ruta, es obligatorio. Para obtener más información, lea http://www.tldp.org/LDP/Bash-Beginners-Guide/html/sect_02_01.html

+4

... FYI, en #bash en irc.freenode.org, estamos corrigiendo constantemente los malentendidos que las personas han aprendido de TLDP (particularmente la guía avanzada Bash). Como tal, dirigir personas allí es ... quizás no ideal. (Nuestra documentación introductoria preferida es http://mywiki.wooledge.org/BashGuide) –

3

Cuando incluye el '.' esencialmente estás dando la "ruta completa" al script bash ejecutable, por lo que tu shell no necesita verificar tu variable PATH. Sin el '.' su shell buscará en su variable PATH (que puede ver al ejecutar echo $PATH para ver si el comando que escribió vive en alguna de las carpetas de su RUTA).Si no lo hace (como es el caso de manage.py), dice que no puede 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.html

1

En * nix, a diferencia de Windows, el directorio actual no está generalmente en su variable $PATH. Por lo tanto, el directorio actual no se busca al ejecutar comandos. No necesita ./ para ejecutar aplicaciones porque estas aplicaciones son en su $ PATH; lo más probable es que estén en /bin o /usr/bin.

41

Cuando bash interpreta la línea de comando, busca comandos en las ubicaciones descritas en la variable de entorno $PATH. Para verlo escriba:

echo $PATH 

Tendrá algunas rutas separadas 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 por tener:

PATH=$PATH:. 

Esta línea añade el directorio actual en $PATH por lo que se puede hacer:

manage.py syncdb 

Es no recomienda ya que tiene problema de seguridad, además de que puede tener comportamientos extraños, como . varía en el directorio en el que están en :)

Evitar:

PATH=.:$PATH 

Como se puede “enmascarar” algún comando estándar y abrir la puerta a la violación de la seguridad :)

Sólo mis dos centavos.

-5

Hay una diferencia entre Current Directory y Working Directory puede encontrarlo en google fácilmente. Esa es la razón por la cual su manage.py syncdb no se ejecutó como se esperaba.

Directorio actual: Es el directorio desde el que se ejecuta el shell o el proceso primario.

you are right "." is for current directory. 

En el sistema basado en UNIX si usted tiene su archivo en /data/myfile.out entonces usted está cruzando transversalmente a su archivo a través de nombres de los componentes que están separados por forward slash "/" así que si "." es el directorio actual a continuación, si desea acceder (ejecutar en su caso) archivo que está dentro de su directorio actual tendrá que decir ./myexecutableFile.o. Si tuviera su archivo ejecutable en otra carpeta de su directorio actual, entonces haría algo como esto ./myFiles/myexecutableFile.o. Espero que tengas lo que intento explicar.

1

Esta cuestión ya tenga algunas respuestas impresionantes, pero quería añadir que, si el ejecutable está en el camino, y se obtiene muy diferentes salidas cuando se ejecuta

./executable 

a los que te dan si ejecutar

executable 

(digamos que se ejecuta en los mensajes de error con uno y no el otro), entonces el problema podría ser que usted tiene dos versiones diferentes del ejecutable en su máquina: uno en el camino, y la otro no

comprobarlo ejecutando

cuales ejecutable

y

whereis executable 

Se fija mis problemas ... Yo tenía tres versiones del ejecutable, solamente uno de los cuales se compilan correctamente para el ambiente.

Cuestiones relacionadas