¿Hay alguna diferencia entre las rutas de "archivo" y "./file"?


12

Como dice el título, ¿hay alguna diferencia para los sistemas de archivos * NIX? por ejemplo ls fileyls ./file


1
Puede preguntarle a unix.stackexchange.com : las respuestas hasta ahora tienen buena información, pero ninguna de las dos parece ser la respuesta.
Rob Starling

Respuestas:


14

No estoy loco por la explicación de SmallLoanOf1M. Es técnicamente correcto pero responde de una manera que no coincide con el ejemplo de uso en la pregunta.

A modo de ejemplo, aquí hay una diferencia importante entre los dos de la pregunta: "archivo" y "./file"

¿Qué sucede si el archivo se nombra con un carácter analizado por el shell? Especialmente con respecto a los caracteres interpretados por el comando que se está ejecutando.

Específicamente, el carácter "guión": "-". Pero otros personajes son significativos para el caparazón.

Ejemplo. Mi archivo se llamaba "-dingle"

Intenta enumerar el archivo:

ls -dingle
# ls -dingle
ls: invalid option -- 'e'

Peor aún, ¿qué pasa si el archivo se llamaba " -rf rmbomb *"? Ahora intenta eliminarlo

rm "-rf rmbomb *"

Ni siquiera voy a tratar de ejecutar ese ejemplo, pero espero que entiendas la idea.

Entonces, ¿cómo enumeras un archivo que mira con guión? Uso ./en frente.

# ls ./-dingle
./-dingle

Lo mismo para rm


Esa es una forma válida de procesar algunos archivos con nombres extraños, y mi respuesta no consideró archivos como ese. También se podría usar un literal en su lugar en todos los ejemplos anteriores, en forma de barra diagonal inversa que precede a los caracteres impares, incluidos los espacios especificados anteriormente. Un ejemplo de eso sería así: ls \-dingleo ls \-rf\ rmbomb\ \*. Esta puede ser una buena manera de garantizar que cualquier conjunto de comandos dado sea al menos coherente, ya que especificar ./antes de un nombre no escapará de los caracteres después de ./.
Spooler

2
Sucede que, dado que el shell escapa a los escapes, no el comando, y los parámetros son analizados por el comando, escapando o citando el - no hace nada útil.
Dewi Morgan

2
Haces que parezca rm "-rf rmbomb *"que realmente haría algo malo, en lugar de simplemente hacer que la rmimpresión sea un error. Solo es peligroso si olvida citar el nombre del archivo, por lo que se divide la palabra. (especialmente en un script de shell donde ejecuta en rm $filelugar de rm "$file". Pero en ese caso, el *no se expandirá, porque la expansión global no ocurre en el contenido de la expansión variable. Si lo desea, necesitaría un eval.) De todos modos, si su script divide los nombres de los archivos antes de pasarlos a rm, haría un archivo llamado space -rf .o algo así, así rm ./$ique no ayuda.
Peter Cordes

1
Por cierto, el mensaje de error real es rm: invalid option -- ' ', cuando trata de interpretar el espacio después -rfcomo un cambio de un solo carácter, porque es parte del mismo argumento. (Y sí, ejecuté esto dentro de un directorio vacío en caso de que haya pasado por alto algo y realmente fuera peligroso: P)
Peter Cordes

2
@PeterCordes: la división de palabras y el globbing SÍ ocurren en los resultados de la expansión de variables sin comillas y la sustitución de comandos, a menos que se supriman por IFS=''y -frespectivamente. Un ejemplo más raro es que awktrata un operando (que no sea el primer operando que es el script) que tiene forma foo=barcomo una tarea para ejecutar pero ./foo=barcomo un archivo para leer.
dave_thompson_085

7

Si.

Al emitir fileen la línea de comando, BASH buscará en su variable de entorno $ PATH un archivo con ese nombre. A menos que el archivo resida en un directorio dentro de su variable $ PATH, no se encontrará.

.significa el directorio actual. ./significa dentro del directorio actual, en términos relativos. Es el equivalente a decir algo así como /home/sheogorath/shivering/isles.imgcuando se invoca ./isles.imgmientras se trabaja en el /home/sheogorath/shivering/directorio.

Como tal, se usa comúnmente para ejecutar archivos dentro de su directorio de trabajo "en su lugar".

EDITAR: en su ejemplo, lsel shell lo invoca y lo encuentra utilizando la variable de ruta. Su argumento se procesará en su directorio de trabajo, sea lo que sea. Dado que este es el valor predeterminado para ls, no verá ninguna diferencia entre especificar filey especificar explícitamente, ./fileya que ambos apuntan a su directorio actual.

No todos los comandos aceptarán rutas de archivos en el directorio de trabajo, y algunos esperan que usted establezca los archivos en un directorio que ellos mismos predefinen mediante la configuración. Entre los comandos que aceptan archivos como argumentos, estos comandos son menos comunes


1
Eso es bash, pero me preguntaba sobre la resolución del camino en general
Sergey Alaev

1
Esta es la forma en que funciona cualquier shell que he oído hablar. BASH es simplemente el más utilizado.
Spooler

44
$ PATH solo es relevante para los comandos y no tiene nada que ver con los argumentos de nombre de archivo que siguen a un comando como se lsmenciona en la pregunta original. Esa es más la diferencia entre hacer referencia a una ruta relativa (relativa al directorio de trabajo actual) Ie ../../dir/filenamey una ruta absoluta /path/to/dir/filename
HBruijn

1
+1 para Sheogorath ... y una respuesta correcta.
Corey Ogburn

1
Si son argumentos de un comando que intenta encontrar archivos en el directorio de trabajo de forma predeterminada, serán los mismos. Por lo tanto, porque lssiempre serán la misma ruta, una especificada más explícitamente que la otra. No todos los comandos se comportan de esta manera cuando procesan argumentos, pero la mayoría sí.
Spooler
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.