¿Por qué usamos ./filename
para ejecutar un archivo en Linux?
¿Por qué no simplemente ingréselo como otros comandos gcc
, ls
etc …
Comentarios
Responder
En Linux, UNIX y sistemas operativos relacionados, .
denota el directorio actual. Dado que desea ejecutar un archivo en su directorio actual y ese directorio no está en su $PATH
, necesita el ./
bit para decirle al shell dónde el ejecutable es. Entonces, ./foo
significa ejecutar el ejecutable llamado foo
que se encuentra en este directorio.
Puede usar type
o which
para obtener la ruta completa de cualquier comando que se encuentre en su $PATH
.
Comentarios
- Es muy común ejecutar programas en el directorio actual. ¿Por qué no ‘ la búsqueda de shell allí también? Primero busca en., Luego en $ PATH.
- También hay
alias
que pueden estorbar, no solo$PATH
. - @Michael seguridad y cordura: si buscara en
.
primero, entonces sería un problema de seguridad, usted o alguien más podría reemplazarls
por ejemplo (un virus / trojen simple: crea un archivo zip con un ejecutable llamadols
en él, mientras alguien está buscando, ejecutan este ejecutable, ese …). Si buscó en.
la última vez, entonces puede pasar mucho tiempo volviéndose loco sin saber por qué su programa no está funcionando (por ejemplo, crea un programa llamado prueba, en lugar de ejecutar su programa, se ejecuta el programa de prueba del sistema, que no produce salida). - @jcubic que ‘ es una mala idea. Vea el comentario anterior. En el pasado, DOS buscaba en el directorio actual y ese comportamiento se trasladaba al cmd de Windows, lo que presenta muchos problemas de seguridad. MS arregló eso en PowerShell y ahora debe usar. \ Para ejecutar el programa en el directorio actual
- @ ctrl-alt-delor: Cuando estaba en la universidad a finales de los 80 ‘ s, esta era una táctica común (prohibida). Escribir un programa » ls » y dejarlo en tu carpeta de inicio en caso de que alguien más venga husmeando. El programa se denominó » get shell » IIRC. Intentaría obtener las credenciales del usuario que ejecuta el comando, y luego tal vez imprimir una lista de directorio falsa para no saberlo.
Respuesta
La respuesta literal es la que otros han dado: porque el directorio actual no está en su $PATH
.
Pero ¿Por qué? En resumen, es por seguridad. Si «estás buscando en el directorio de inicio de otra persona» (o / tmp) y escribes solo gcc
o ls
, quieres sabe que está ejecutando la versión real, no una versión maliciosa que su amigo bromista ha escrito y 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 integrados.
Tener .
como la última entrada en su ruta es un poco más segura, pero hay otros ataques que hacen uso de eso. Una fácil es aprovechar los 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 al promedio de escribir eso.
¿Suena esto demasiado teórico? En gran medida lo es, pero definitivamente puede suceder en la realidad, especialmente en sistemas multiusuario. De hecho, aquí hay un ejemplo de este sitio donde un administrador cambió al «directorio de inicio de un usuario y encontró ps
para ser enmascarado por un ejecutable con ese nombre.
Comentarios
- Solo tenga rutas absolutas en el
PATH
variable de entorno.
Respuesta
Si te refieres, ¿por qué lo necesitas?/ al principio – eso es porque (a diferencia de Windows), el directorio actual no es parte de su ruta por defecto. Si ejecuta:
$ 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 escribe:
$ a.out
el shell hará lo mismo, pero probablemente no encontrará un ejecutable llamado a.out. Necesita decirle al shell dónde a.out está – está en el directorio actual (.) entonces la ruta es ./a.out
.
Si estás preguntando 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
Comentarios
- Gracias. Mi duda es por qué necesitas ./ al principio … Conseguí el uso de «.» (para ubicar el directorio actual) pero por qué » / » ¿después de eso?
- / es el separador de ruta en Linux, por lo que se usa para separar el directorio (.) del nombre del archivo (a.out). Sin él, tiene .a.out, que es un nombre de archivo por derecho propio. (Prueba
touch .a.out; ls -lA
para ver esto). - así es como especificas el ruta en Unix,
<dir>/<file>
por lo que básicamente está diciendo que ejecute un archivo en el directorio actual, que está indicado por./test
- ¿Red Hat Linux 9? ¡Es hora de actualizar!
- En Windows 10, PowerShell es el shell predeterminado ahora, y también requiere
./
para ejecutar un ejecutable en la ruta actual
Respuesta
Puede 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, Te recomiendo encarecidamente que NO hagas eso. Es malo, malo, malo y malo.
Sabes, ese tipo de cosas funcionan así desde 1970. Hay una razón por la que el directorio actual no está incluido en $ PATH.
.
es el directorio actual
.something
sería un archivo oculto (escriba «ALT +» para hacer aparecen en Nautilus, o pruebe «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.
Respuesta
La regla más completa es en realidad: si hay alguna barra oblicua /
está en la ruta, no» busque PATH
Antes de entrar en el fundamento, primero debe conocer este hecho: ejecutar cualquiera de:
bin/someprog
o:
o:
cd bin ./myexec
ejecutar bin/someprog
sin buscar el PATH
variable por exactamente el mismo motivo: todas las bin/someprog
, /bin/someprog
y ./someprog
tienen una barra /
en ellos.
someprog
por sí solo no tiene una barra /
y, por lo tanto, busca solo en PATH
.
POSIX 7 especifica esta regla en: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_01_01
RUTA
[…] Si el nombre de la ruta que se busca contiene un
<slash>
, la búsqueda a través de los prefijos de la ruta no se realizará .
Justificación de la /
regla POSIX PATH
Supongamos que se ejecuta:
someprog
buscaría:
- relativo a CWD primero
- relativo a PATH después
Luego, si desea ejecutar /bin/someprog
de tu distribución, y lo hiciste:
someprog
algunas veces funcionaría, pero otras fallaría, porque es posible que se encuentre en un directorio que contenga otro programa someprog
no relacionado.
Por lo tanto, pronto aprenderá que esto no es confiable y que siempre terminará usando rutas absolutas cuando desea usar PATH, por lo tanto, anula el propósito de PATH.
Esta es también la razón por la que tener rutas relativas en su PATH es una muy mala idea. Estoy mirándote, node_modules/bin
.
Por el contrario, suponga que ejecutando:
./someprog
Buscaría:
- relativo a PATH primero
- relativo a CWD después de
Entonces, si acaba de descargar un script someprog
de un repositorio de git y desea ejecutarlo de CWD, nunca estarías seguro de que este es el programa real que se ejecutaría, porque tal vez tu distribución tenga un:
/bin/someprog
que está en tu PATH desde algún paquete que instaló después de beber demasiado después de la Navidad del año pasado.
Por lo tanto, una vez más, se vería obligado a ejecutar siempre scripts locales relativos a CWD con rutas completas para saber qué está ejecutando:
"$(pwd)/someprog"
lo cual también sería extremadamente molesto.
Otra regla que podría tener la tentación de proponer sería:
las rutas relativas usan solo PATH, las rutas absolutas solo CWD
pero, una vez más, esto obliga a los usuarios a siempre usa abso rutas de laúd para scripts que no son PATH con "$(pwd)/someprog"
.
La regla de búsqueda de rutas /
ofrece una solución fácil de recordar al problema acerca de:
- barra oblicua: no use
PATH
- no barra oblicua: solo use
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
, por lo que le da un significado especial a uno de ellos.
A veces, es un poco molesto que no puedas buscar para some/prog
relativo a PATH
, pero no veo una solución más sensata para esto.
./command_name
para ejecutar un comando en linux? »