¿Diferencia entre los comandos de terminal 'dir' y 'ls'?

74

He estado tratando de encontrar la diferencia entre usar los comandos diry lsen la terminal. Sé que ls es el método tradicional de UNIX para ver los archivos en un directorio, y ese dires el símbolo del sistema de Windows equivalente, pero ambos comandos funcionan en la terminal.

Si escribo dir, muestra los archivos y las carpetas en el directorio, y si escribo lshace lo mismo, excepto con resaltado de contenido. Ambos comandos aceptan opciones (es decir, ls -ay dir -aambos devuelven todos los archivos y carpetas y archivos ocultos).

Así que ¿alguien sabe cuál es la diferencia y por qué tanto diry lsse utilizan?

BretD
fuente
77
dir --color;)
Rinzwind
3
Solo quería decir que estoy sorprendido por la cantidad de respuesta que ha recibido esta pregunta. Creo que no fui el único que se preguntaba sobre esto :)
BretD
3
Los comandos de la antigüedad siempre arrastran a los nerds más viejos fuera de la carpintería;)
Rinzwind

Respuestas:

70

diry lsson parte de coreutilsy dires casi lo mismo que ls, solo que con diferentes opciones predeterminadas.

Las GNU Core Utilities son las utilidades básicas de manipulación de archivos, shell y texto del sistema operativo GNU. Estas son las utilidades principales que se espera que existan en cada sistema operativo.

info dir dice:

dires equivalente a ls -C -b; es decir, los archivos predeterminados se enumeran en columnas, ordenados verticalmente, y los caracteres especiales se representan mediante secuencias de escape de barra invertida.

¡Ah, y también hay vdir! info vdirdice:

vdires equivalente a ls -l -b; es decir, los archivos predeterminados se enumeran en formato largo y los caracteres especiales se representan mediante secuencias de escape con barra invertida.

Lo más probable es que direxista por compatibilidad con versiones anteriores o por razones históricas.

Rinzwind
fuente
Estaba pensando que probablemente era solo un alias del otro. Asumí que el razonamiento era hacer que los usuarios de Windows se sintieran más como en casa.
BretD
44
escriba alias dirpara ver qué es realmente. escriba aliaspara ver todos los alias.
user606723
2
@ user606723, 'alias dir' no se muestra en 11.10 (al menos no para mí). Creo que 'alias' solo muestra la configuración de alias del usuario local, no todo el sistema.
James
escriba type dirpara ver qué es (un alias, un comando, una función bash ...)
ychaouche el
49

La relación entre lsydir

lsy dirson programas separados que se comportan de manera similar. Como se explica y hace referencia a continuación, el propósito de dires proporcionar un comando como lscuya salida no varía dependiendo de si va a un terminal o no . Para lograr esto de manera útil, dirdebe formatear su salida de manera razonable y útil tanto para ver en un terminal como para escribir en un archivo o canalización.

Hay dos conceptos erróneos comunes sobre dir:

  • Mucha gente cree que dires un alias de ls, pero ese no es el caso. Ninguno de los comandos es un alias del otro, y por defecto en Ubuntu, dirno es un alias en absoluto. lsy dirson proporcionados por ejecutables separados, no idénticos.
  • Mucha gente cree que direxiste por razones históricas oscuras o para proporcionar compatibilidad con algún estándar u otro sistema operativo. Ese tampoco es el caso. lsse comporta como lo hace para la compatibilidad. dir, que no tiene que ser compatible porque no es un comando estándar de Unix, se comporta de una manera alternativa que los desarrolladores consideran valioso por sí mismo y posiblemente incluso preferible.

OK, pero ¿exactamente cómo lsy cómo dirdifieren?

Ambos lsy direnumerar el contenido de los directorios. Dos diferencias específicas en sus comportamientos predeterminados los distinguen.

  1. Cuando su salida estándar es una terminal, lsenumera los nombres de los archivos en columnas ordenadas verticalmente (como ls -C). Cuando su salida estándar no es una terminal (por ejemplo, un archivo o una tubería ), lsenumera los nombres de los archivos uno por línea (como ls -1).

    Si su salida estándar es o no una terminal, direnumera los nombres de los archivos en columnas ordenadas verticalmente (como ls -C).

    Por tanto lsy dir, estos valores predeterminados pueden ser anulados por la --format=bandera y por los -1, -C, -m, y -xbanderas, que abrevian particulares --format=opciones. Consulte 10.1.4 Formato de salida general en el manual de referencia de GNU coreutils para más detalles.

  2. Cuando su salida estándar es un terminal y un nombre de archivo que se listará contiene caracteres de control , se lsimprime en ?lugar de cada carácter de control (como ls -q). Cuando su salida estándar no es una terminal, lsimprime los caracteres de control tal cual (como ls --show-control-chars).

    Ya sea que su salida estándar sea o no un terminal, cuando direncuentra un carácter de control o cualquier otro carácter que se interpretaría especialmente si se ingresara en un shell, imprime secuencias de barra invertida para los caracteres. Esto incluye incluso caracteres relativamente comunes como los espacios. Por ejemplo, direnumerará una entrada llamada Documents backupscomo Documents\ backups. Esto es como ls -b.

    Para ambos lsy dir, estos valores predeterminados pueden ser anulados por los indicadores enumerados en 10.1.7. Formateo de los nombres de archivo en el manual de referencia de GNU coreutils . Esto incluye -b, -q, --quoting-style=, y algunos otros.

Fuentes : invocación ls e invocación dir , en el manual de referencia de GNU coreutils .

¿Por qué tener dir?

La justificación de una dirutilidad separada se da en 4.5 Estándares para interfaces Generalmente de los estándares de codificación GNU . Recomiendo leer toda la sección para comprender el razonamiento de los desarrolladores, pero aquí están los aspectos más destacados según corresponda a ls/ dir:

No haga que el comportamiento de una utilidad dependa del nombre utilizado para invocarla ...

En su lugar, use una opción de tiempo de ejecución o un interruptor de compilación o ambos para seleccionar entre los comportamientos alternativos ...

Del mismo modo, no haga que el comportamiento de un programa de línea de comandos dependa del tipo de dispositivo de salida ...

La compatibilidad requiere que ciertos programas dependan del tipo de dispositivo de salida. Sería desastroso si lo hiciera lso shno de la manera que todos los usuarios esperan. En algunos de estos casos, complementamos el programa con una versión alternativa preferida que no depende del tipo de dispositivo de salida. Por ejemplo, proporcionamos un dirprograma muy parecido, lsexcepto que su formato de salida predeterminado es siempre un formato de varias columnas.

El Proyecto GNU considera indeseable, desde una perspectiva técnica, que una utilidad produzca resultados diferentes dependiendo de qué tipo de dispositivo está escribiendo (al menos en la configuración predeterminada de la utilidad). Para algunas utilidades, incluida la lssalida dependiente del dispositivo, es necesaria para la compatibilidad, por lo que funciona de la manera que los usuarios esperan. Algunos usuarios también prefieren específicamente este comportamiento dependiente del dispositivo.

Si bien lsno se pudo escribir razonablemente para comportar el dispositivo de forma independiente, dirse creó una utilidad separada para lograr esto. Por lo tanto dirno es la utilidad que comporta de forma extraña por razones de compatibility-- histórica lses .

Para ver cómo ls, diry la relacionada vdirutilidad se implementan en el código fuente coreutils sin duplicación innecesaria de código, vea ls-dir.c, ls-ls.c, ls-vdir.c, ls.h, y ls.c.

¿Es dirrealmente útil?

Si alguna vez ha deseado lsproducir una salida de varias columnas, incluso cuando la canalizó a less( ls | less) o la redirigió a un archivo ( ls > out.txt), puede usar diro ls -C.

Si alguna vez ha deseado poder copiar directamente un nombre de archivo que se muestra lsy usarlo como parte de un comando sin preocuparse por las citas , puede usar diro ls -b.

dires equivalente a ls -Cb, por lo que en ese sentido no es necesario dir. Pero dirproporciona una combinación de opciones que en la práctica a menudo es útil (aunque no se conoce ampliamente).

¿Por qué obtengo resultados coloreados de ls(incluso ls -Cb) pero no dir?

La mayoría de los usuarios de Ubuntu tienen un alias llamado lsque se ejecuta ls --color=auto. Cuando lsexiste tanto como un alias como un comando externo, el alias tiene prioridad en los comandos simples e interactivos.

Las definiciones de alias no se expanden recursivamente: es el lscomando externo con el que lsestá llamando el alias --color=auto. Consulte 6.6 Alias en el manual de referencia de Bash para obtener más información sobre cómo funcionan los alias.

Cuando se pasa a ls, diro vdir(y algunos otros comandos, como grep), --color=autousa color cuando su salida es un terminal, pero no de otra manera.

Por defecto en Ubuntu, las cuentas de usuario se crean con esto en ~/.bashrc:

# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
    test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
    alias ls='ls --color=auto'
    #alias dir='dir --color=auto'
    #alias vdir='vdir --color=auto'

    alias grep='grep --color=auto'
    alias fgrep='fgrep --color=auto'
    alias egrep='egrep --color=auto'
fi

Notarás que el lsalias ( alias ls='ls --color=auto') no está comentado , mientras que los de diry vdirestán comentados, por #lo que no tienen efecto. Es decir, si bien dirno es un alias, lses (pero no lo es dir) .

¿Cómo hago para que también se dirproduzcan resultados en color?

Para habilitar la salida en color con dir, simplemente edite .bashrcen su directorio de inicio y #alias dir='dir --color=auto'elimine el comentario de la línea eliminando el encabezado #. En los depósitos iniciados después del cambio, dirhabrá un alias.

Si desea el cambio en el shell actual, puede ejecutar la definición de alias como un comando, o puede obtenerla .bashrcejecutando . ~/.bashrc.

Esto podría ir en contra del punto principal de dirque debería producir el mismo tipo de salida independientemente del dispositivo de salida. Sin embargo:

  • Si le resulta útil hacer este diralias, debería hacerlo.
  • Cuando se llama como un comando externo, por ejemplo en scripts o si anula el alias ejecutando \diro command dir, dirseguirá produciendo una salida independiente del dispositivo. Esto quiere decir que el alias dira dir --color=autono se rompe realmente dir.
Eliah Kagan
fuente
Respuesta de calidad, pero podría usar un ToC o TL; DR; :)
Kevin
5

Me inclinaría a pensar que direxiste solo por compatibilidad con versiones anteriores .

De GNU Coreutils :

dir es equivalente a ls -C -b; es decir, los archivos predeterminados se enumeran en columnas, ordenados verticalmente, y los caracteres especiales se representan mediante secuencias de escape de barra invertida.

Por cierto, lsno colorear la salida por defecto: esto se debe a que la mayoría de distribuciones de alias lsa ls --color=autoen /etc/profile.d. Para una prueba, escriba y unalias lsluego intente ls: será incoloro.

Fuente: la respuesta de Renan a ¿Cuál es la diferencia entre "dir" y "ls" ?

Zlatan
fuente
A pesar de que dirse no se proporciona por compatibilidad hacia atrás -y lsde hecho es --este respuesta (y la respuesta se cita) no indicar correctamente la diferencia técnica entre los dos comandos, así como la explicación de la diferencia de coloración comúnmente observados. Entonces +1.
Eliah Kagan
3

En caso de duda, compare type lsvs type dir(vea también Diferencia entre ls y la ):

$ type dir
dir is aliased to `ls -l'

$ type ls
ls is aliased to `_ls'

$ type _ls
_ls is a function
_ls ()
{
    local IFS=' ';
    command ls $LS_OPTIONS ${1+"$@"}
}
$ echo command ls $LS_OPTIONS ${1+"$@"}
command ls -N --color=tty -T 0

La diferencia se reduce a diferentes opciones para ls, en mi caso --color=tty, sería la más visible, su sistema puede diferir.

usuario2394284
fuente
2
Esto no parece una configuración de usuario de Ubuntu predeterminada en absoluto. No creo que ninguno de los sistemas Ubuntu que he usado haya tenido lsun alias para una función llamada _ls, ni siquiera como una línea comentada .bashrc. Sin embargo, parece ser el valor predeterminado para (al menos algunas versiones de) openSuSE, a juzgar por esta conversación , este archivo (vinculado desde allí) y mi memoria (es probable que sea incorrecta) de la última vez que utilicé openSUSE.
Eliah Kagan
2
@EliahKagan: ¡Lo has adivinado, estoy usando OpenSuse! Entonces, como dije, el resultado será diferente, pero el método debería estar bien.
user2394284
2

Respuesta corta: Ninguno, dires el mismo que el código fuente ls, lsbinario tiene --colorpor defecto. (1 línea de código dif.)

Francisco Valdez
fuente
77
dires no un alias de ls. Son binarios separados /usr/binque se comportan de manera diferente, como se describe en la respuesta de Rinzwind . Podría lograr esto con alias, pero no es así como se logra. Aparecen binarios y separados en todos los sistemas que usan GNU Coreutils . Si necesitas pruebas, corre . dirlscmp /bin/ls /bin/dir
Eliah Kagan
2
hace algún tiempo era un alias y se podía ver en la lista de alias simplemente escribiendo alias, ahora se compila un nuevo binario para dir. Puede descargar su código con: git clone git://git.sv.gnu.org/coreutils. Sólo se cambia una línea de código en ls-dir.c y es la siguiente: int ls_mode = LS_MULTI_COL;. Técnicamente no es un alias, pero prácticamente es LS pero con diferentes opciones predeterminadas (1 línea de código).
Francisco Valdez
1
Sí, dires lspero con diferentes opciones por defecto . diry lssiempre han sido binarios separados en distribuciones que usan GNU Coreutils. Algunas distribuciones pueden, o pueden haber, también definido un alias llamado dir(es bastante común definir alias que tengan el mismo nombre que un comando existente). Pero son ejecutables separados. Distinguir entre un alias de shell (que no es un archivo en absoluto) y un ejecutable separado con un código fuente similar, no es una distinción pedante. Es falso y engañoso decir que dires un alias de lsUbuntu.
Eliah Kagan
Sí, estoy de acuerdo con usted, pero en este caso, no es un código fuente similar, es el mismo código fuente. Si decimos que un alias es simplemente cualquier cosa enumerada, aliasentonces, por supuesto, no es un alias.
Francisco Valdez
3
No es el mismo código fuente. Como dijiste, "se cambia una línea de fuente". Y si fuera la misma fuente, entonces todavía no sería un alias. Hay un montón de cosas en un sistema Unix que son similares a los alias pero que sería muy confuso para los principiantes (y exasperante para los usuarios experimentados) para llamar a los alias. Los enlaces simbólicos, los enlaces duros, los archivos idénticos, los archivos similares, los scripts de envoltura, los archivos ejecutables ocultos de shell y los archivos sincronizados (por ejemplo, con UbuntuOne) son similares a los alias de manera significativa, pero no son alias.
Eliah Kagan