¿Es ./ (barra diagonal) un comando?

16

Núcleo de la pregunta:

La pregunta surgió cuando no pude instalar el software, por lo que realmente estoy preguntando acerca de ./ porque no lo sabía y el resultado "comando no encontrado" me estaba confundiendo acerca de lo que realmente era el comando.

Contexto:

Me gustaría instalar el archivo truecrypt-7.2-setup-x86.

Las instrucciones dicen que use el comando:

sudo ./truecrypt-7.2-setup-x86

Pero el resultado es:

sudo: ./truecrypt-7.2-setup-x86: command not found

ACTUALIZACIÓN: para completar, en la prueba estaba en la carpeta de archivos pero aún no había hecho el archivo ejecutable (chmod + x).

ubuntubu
fuente
1
La ./parte del comando dice "Buscar en el directorio actual y ejecutar el comando 'truecrypt-7.2-setup-x86' desde aquí". Debe ejecutar este comando desde el directorio donde descomprimió el archivo.
Charles Green
2
@Videonauth - No realmente, personalmente no creo que eleve al nivel de una respuesta.
Charles Green
1
@Zanna Probé un script sin permisos de ejecución, y el error arrojado fue un error de permiso faltante, no un comando no encontrado.
Charles Green
2
@ubuntubu OK, muy bien, te has mudado al directorio - bien. Pequeño comentario sobre la edición, sin embargo. El comando debería ser chmod +x, chmod -xes todo lo contrario: elimina los permisos ejecutables
Sergiy Kolodyazhnyy
44
El título de la pregunta es bastante diferente del cuerpo; tal vez eso debería ser arreglado?
David Z

Respuestas:

24

./No es un comando. El comando es ./truecrypt-7.2-setup-x86.

Su shell y programas como sudotratarán un comando como un nombre de ruta cuando contenga al menos un /carácter. Como .representa el directorio en el que se encuentra actualmente, ./truecrypt-7.2-setup-x86nombra el archivo truecrypt-7.2-setup-x86en el directorio actual. Si no existe dicho archivo, o si existe pero el archivo no se puede ejecutar, recibirá un mensaje de error.

Cuando un comando no contiene una barra oblicua, $PATHse busca en los directorios enumerados , como dice Sergiy Kolodyazhnyy . El directorio actual no es automáticamente buscó - y se no se recomienda poner .en $PATH. De esa manera, no ejecuta accidentalmente cosas que no esperaba ejecutar porque resultó que tenía cdun directorio d que las contiene.

Escribir ./antes del nombre de un ejecutable en el directorio actual la forma común de ejecutarlo, pero esta no es realmente una sintaxis especial. Por ejemplo, si cometió un error $PATHy necesita ejecutar un comando como ls, podría escribir /bin/ls. No .es necesario en ese caso o en general; lo que se necesita es un /lugar en el nombre de ruta para indicar que quiere decir que es un nombre de ruta.

Como .siempre es el directorio actual y /es solo el separador de directorios, lo primero que debe hacer es verificar que el archivo que ha nombrado realmente exista en el directorio actual. (Si lo hace, verifique sus permisos , como explica Charles Green . Pero si extrajo el archivo de un archivo comprimido, generalmente ya tendrá permisos ejecutables si está destinado a ejecutarse).

Eliah Kagan
fuente
21

La parte ./ del comando dice "Busque en el directorio actual y ejecute el comando 'truecrypt-7.2-setup-x86' desde aquí". Debe ejecutar este comando desde el directorio donde descomprimió el archivo.

Esto se puede probar: en la misma ventana de terminal donde está probando el comando, ingrese el comando ls -l true*; si el archivo está presente en el directorio de trabajo actual, se mostrará una lista que muestra el archivo (y un montón de información adicional).

Como Zanna ha señalado en los comentarios, es posible que su archivo no tenga permisos de ejecución; esto se puede solucionar fácilmente. Como caso de prueba, mi directorio muestra

chick@dad:~/test$ ls -l
total 4
-rw-r--r-- 1 chick chick 788 Oct 27 06:15 rFullBack
chick@dad:~/test$

y el archivo "rFullBack" enumera '-rw-' como mi permiso para leer y escribir el archivo. Puedo ejecutar el comando chmod +x rFullBacky la lista de directorios cambia a

chick@dad:~/test$ ls -l
total 4
-rwxr-xr-x 1 chick chick 788 Oct 27 06:15 rFullBack
chick@dad:~/test$

Allí mis permisos ahora son '-rwx', lo que indica que puedo ejecutar el archivo.


En resumen, si el archivo existe en su directorio

ejecuta el comando

chmod +x ./truecrypt-7.2-setup-x86

y luego el comando

sudo ./truecrypt-7.2-setup-x86
Charles Green
fuente
1
No exactamente. Enumera rw-como su permiso, el -antes es para establecer [gu] id y bits fijos.
Duncan X Simpson
@DuncanXSimpson Gracias: actualicé un poco la descripción de los permisos, ¡pero voy a ignorar los bits fijos y fijos para esta respuesta!
Charles Green
8

¿Cómo funcionan los comandos de llamada en shell?

No, no es un comando. La forma en que funcionan los shells es cuando escribe una línea de texto, la primera palabra se tratará como comando, y si el comando no es uno de los shell incorporados, el shell buscará en todas las ubicaciones enumeradas en PATH la variable de entorno .

¿Qué sucede si el comando que desea ejecutar está en el mismo directorio en el que se encuentra actualmente pero ese directorio no está en la lista de PATHdirectorios? Ahí es cuando necesitas usar ./. Es exactamente lo mismo que hacer /bin/bash: le está diciendo al shell dónde se encuentra su comando deseado, una ruta completa hacia él. Y en el caso de ./ usted está diciendo que "busque en este directorio". Tan importante es que debe estar en el mismo directorio donde se encuentra el archivo.

Por supuesto, para ejecutar realmente un ejecutable, debe tener un conjunto de bits ejecutable, por lo que deberá hacerlo chmod +x ./my_file.

Entonces los pasos importantes:

  1. cd donde guardó el archivo; si está adentro ~/Downloads, entoncescd ~/Downloads
  2. Ejecutar chmod +x ./truecrypt-7.2-setup-x86, esto dice "hacer ejecutable el archivo truecrypt-7.2-setup-x86 que está en este directorio"
  3. Y ahora hazlo sudo ./truecrypt-7.2-setup-x86

Tenga en cuenta que el uso de ./no es un comportamiento aleatorio, pero en realidad es un estándar, especificado por el estándar de la interfaz del sistema operativo portátil (también conocido como POSIX) , consulte específicamente la sección "Búsqueda y ejecución de comandos".

Reproduciendo el error

$ # my script is in ~/Downloads folder
$ stat -c "%n" /home/xieerqi/Downloads/my_script.sh                         
/home/xieerqi/Downloads/my_script.sh
$ # if I run sudo ./my_script.sh, we get an error
$ sudo ./my_script.sh
[sudo] password for xieerqi: 
sudo: ./my_script.sh: command not found
$ # of course the command not found because file is not in ./, not in this dir
$ # this is not  sudo's problem
$ # but sudo does indeed show the same error even if you're in same directory
$ cd ./Downloads/                                                                                                                                                      
$ sudo ./my_script.sh                                                                                                                                                  
[sudo] password for xieerqi: 
sudo: ./my_script.sh: command not found

NOTA : el mensaje de error dado por sudoes obviamente engañoso, por lo que es algo a tener en cuenta; sin embargo, tenga en cuenta que este no era el núcleo de la pregunta que OP está haciendo.

Documentación y referencias.

Del bashmanual 4.3, sección "EJECUCIÓN DE MANDO":

Si el nombre no es una función de shell ni una función integrada, y no contiene barras, bash busca en cada elemento de la RUTA un directorio que contenga un archivo ejecutable con ese nombre.

De ¿Por qué necesita ./ (punto-raya vertical) antes del nombre de secuencia de comandos para ejecutarlo en bash? :

Funciona con ./ porque POSIX especifica que un nombre de comando que contiene un / se usará 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.

Sergiy Kolodyazhnyy
fuente
En realidad, la sudoproducción es engañosa. Si intenta lo mismo sin sudo, obtendrá otro error de bash: Permission denied. Y con razón, ya que no le ha dado permiso al script para ejecutar (vía chmod +x).
Ruslan
@Ruslan el hecho de que la sudosalida es engañosa es cierto, pero ese es el error que aparece. Eso podría ser algo para informar a los desarrolladores y dejar que lo arreglen. Sin embargo, este no es el núcleo de la discusión: necesitábamos establecer qué ha hecho OP para producir dicho error y guiarlos hacia el camino correcto. Si es o no engañoso, ese no es el problema aquí.
Sergiy Kolodyazhnyy
De otra manera, no es exactamente lo mismo que usar /bin/bash: no le permite ejecutar un script en el que no tiene permiso de ejecución. Cuando introduce el nombre del script /bin/bash, el hecho de que /bin/bashsea ​​ejecutable es lo único que importa, ya que es el comando que se ejecuta. Cuando no hace eso, el script en sí se está ejecutando, lo que a su vez conduce a #!que se invoque su shell actual o lo que sea que esté en la línea superior
Monty Harder
@MontyHarder /bin/bashes simplemente un ejemplo aquí. El hecho de que estamos llamando /bin/bashy ./script.sh especificando la ruta a la cosa que se está ejecutando , es lo mismo. Prefacioar script con bash script.sho /bin/bash script.shes un tema completamente diferente, donde ejecuta un ejecutable y le pasa un script como argumento, que por cierto puede romperse si la sintaxis se escribe para algo diferente al shell que está llamando, por ejemplo csh. /bin/bashes ejecutable bien, pero el hecho es que todavía está especificando la ruta completa a él.
Sergiy Kolodyazhnyy
2
@SergiyKolodyazhnyy Prefacio a un nombre de script con /bin/basho incluso simplemente bashes también una forma común de resolver la falta de permisos ejecutables en el script. Especificar la ruta completa del script no resuelve ese problema. Entonces, /bin/bashes un ejemplo particularmente malo en este caso específico.
Monty Harder