¿Por qué usamos ./filename
para ejecutar un archivo en Linux?
¿Por qué no simplemente ingresarlo como otros comandos gcc
, ls
etc ...
En Linux, UNIX y sistemas operativos relacionados, .
denota el directorio actual. Como desea ejecutar un archivo en su directorio actual y ese directorio no está en su $PATH
, necesitas el ./
bit para decirle al Shell dónde está el ejecutable. Entonces, ./foo
significa ejecutar el ejecutable llamado foo
que está en este directorio.
Puede usar type
o which
para obtener la ruta completa de cualquier comando que se encuentre en su $PATH
.
La respuesta literal es como otros han dado: porque el directorio actual no está en su $PATH
.
Pero ¿por qué? En resumen, es por seguridad. Si está buscando en el directorio de inicio de otra persona (o/tmp), y escribe solo gcc
o ls
, quiere saber que está ejecutando el verdadero, no una versión maliciosa su bromista amigo ha escrito que borra todos sus archivos. Otro ejemplo sería test
o [
, que podría anular esos comandos en los scripts de Shell, si su Shell no los tiene como incorporados.
Teniendo .
como la entrada última en su ruta es un poco más segura, pero hay otros ataques que hacen uso de eso. Una fácil es explotar errores tipográficos comunes, como sl
o ls-l
. O bien, busque un comando común que no esté instalado en este sistema: vim
, por ejemplo, ya que los administradores de sistemas tienen una probabilidad superior a la media para escribir eso.
Si quiere decir, ¿por qué necesita ./ al principio? Eso es porque (a diferencia de Windows), el directorio actual no es parte de su ruta de forma predeterminada. Si tu corres:
$ ls
su Shell busca ls
en los directorios de su variable de entorno PATH (echo $PATH
para verlo), y ejecuta el primer ejecutable llamado ls
que encuentra. Si escribes:
$ a.out
shell hará lo mismo, pero probablemente no encontrará un ejecutable llamado a.out. Debe indicarle al Shell dónde está a.out: está en el directorio actual (.) Y luego la ruta es ./a.out
.
Si se pregunta por qué se llama "a.out", ese es solo el nombre del archivo de salida predeterminado para gcc. Puede cambiarlo con la línea de comando -o arg. Por ejemplo:
$ gcc test.c -o test
$ ./test
Puedes intentar agregar :.
a su variable $ PATH.
Pruebe ALT + F2 y escriba: gksudo gedit /etc/environment
si ejecuta Linux/GTK (esto es lo que tiene si usa Ubuntu).
SIN EMBARGO, le recomiendo que NO haga eso. Es malo, malo, malo y malo.
Ya sabes, ese tipo de cosas funcionan así desde 1970. Hay una razón por la cual el directorio actual no está incluido en $ PATH.
.
es el directorio actual
.something
sería un archivo oculto (escriba "ALT +" para que aparezcan en Nautilus, o intente "ls -la
".
./someProgram.sh
es lo que escribe para EJECUTAR un ejecutable someProgram.sh en el directorio actual.
.somethingElse
significaría que tiene un ejecutable oculto en el directorio actual, lo cual es una mala idea.
La regla más completa es en realidad: si hay una barra inclinada /
En la ruta, no busque PATH
Antes de entrar en la justificación, primero debe saber sobre este hecho: ejecutar cualquiera de:
bin/someprog
o:
/bin/someprog
o:
cd bin
./myexec
ejecute bin/someprog
sin buscar la variable PATH
por la misma razón: todos bin/someprog
, /bin/someprog
y ./someprog
tienen una barra inclinada /
En ellos.
someprog
solo no tiene una barra inclinada /
y, por lo tanto, solo busca en PATH
.
POSIX 7 especifica esta regla en: http: //pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_01_01
Justificación de la regla /
POSIX PATH
Supongamos que se ejecuta:
someprog
buscaría:
Entonces, si quería ejecutar /bin/someprog
Desde su distribución, y lo hizo:
someprog
a veces funcionaría, pero otras fallaría, porque podría estar en un directorio que contiene otro programa someprog
no relacionado.
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 cual tener rutas relativas en su RUTA es una muy mala idea. Estoy mirándote, node_modules/bin
.
Por el contrario, supongamos que se ejecuta:
./someprog
Buscaría:
Entonces, si acaba de descargar un script someprog
de un repositorio 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 tenga un:
/bin/someprog
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:
"$(pwd)/someprog"
lo cual sería extremadamente molesto también.
Otra regla que podría verse tentado a inventar sería:
las rutas relativas solo usan RUTA, las rutas absolutas solo CWD
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
o somefile
, y le da un significado especial a uno de ellos.
A veces, es un poco molesto que no puedas buscar some/prog
En relación con PATH
, pero no veo una solución más sensata para esto.