ls -l --group-directorios-primero (también actúa en enlaces simbólicos)

9

lsLa opción --group-directories-firsthace que los directorios aparezcan en la parte superior, lo que hace que la salida sea lsagradable y limpia:

ls -l --group-directories-first

Sin embargo, no actúa symlinks, que en realidad son symlinksdirectorios. Existe la posibilidad de usar

ls -l -L --group-directories-first

que enumerará ambos tipos de directorios en la parte superior, pero no distinguirá entre el directorio adecuado y el directorio con enlace simbólico, lo que nuevamente es confuso.

¿Puede lsmostrar directorios enlazados en la parte superior, mientras los mantiene distintos de los directorios normales?

EDITAR: estoy usando bash.

Martin Vegter
fuente
Este es un comportamiento idiosincrásico de parte de ls. Según la stat()llamada al sistema, un enlace simbólico a un directorio sigue siendo un directorio ( S_ISDIR(st_mode)devolverá verdadero). Evidentemente lsdescuenta los enlaces simbólicos antes de comprobar esto.
Ricitos
2
@goldilocks, no, lsdoes lstat()(y readlinkpara enlaces simbólicos) a menos que use la -Lopción (en cuyo caso usa stat())
Stéphane Chazelas
@StephaneChazelas: Hmm, vive y aprende. Pensé que eso S_ISLNK(st_mode)también devolvió la vía verdadera stat(), pero no lo hace, solo lo hace a través de lstat(). Además, que ISLNK no devuelve verdadero a través de estadísticas, incluso si el enlace es un enlace a un enlace. Lo que significa que ISLNKla fuerza nunca se devuelve verdadero a través de estadísticas, a pesar de que es una especie de no especificados ...
goldilocks
@goldilocks, statle brinda las propiedades del archivo al final de los enlaces simbólicos. Si eso no existe o no es accesible, statdevuelve ENOENT, por lo que lo que devuelve statnunca será un enlace simbólico. stat()nunca le dirá nada sobre los enlaces simbólicos, al igual openque nunca abrirá el enlace simbólico, o chmod()no cambiará los permisos de un enlace simbólico ... etc.
Stéphane Chazelas

Respuestas:

5

No, pero si lo usa zsh, podría hacer:

mll() {
  (($#)) || set -- *(N-/) *(N^-/)
  (($#)) && ls -ldU -- $@
}

También podría definir un orden de clasificación global como:

dir1st() { [[ -d $REPLY ]] && REPLY=1-$REPLY || REPLY=2-$REPLY;}

y úsalo como:

ls -ldU -- *(o+dir1st)

De esa manera, puede usarlo para otros comandos que no sean lso lscon diferentes opciones, o para diferentes patrones como:

ls -ldU -- .*(o+dir1st) # to list the hidden files and dirs

o:

ls -ldU -- ^*[[:lower:]]*(o+dir1st) # to list the all-uppercase files and dirs

Si tiene que usar bash, el equivalente sería como:

mll() (
  if (($# == 0)); then
    dirs=() others=()
    shopt -s nullglob
    for f in *; do
      if [[ -d $f ]]; then
        dirs+=("$f")
      else
        others+=("$f")
      fi
    done
    set -- "${dirs[@]}" "${others[@]}"
  fi
  (($#)) && exec ls -ldU -- "$@"
)

bashno tiene calificadores de globbing ni ninguna forma de afectar el orden de clasificación de los globs, ni ninguna forma de convertir nullglob en una base por glob, o no tiene un contexto local para las opciones (aparte de comenzar una subshell, por lo tanto, en ()lugar de lo {}anterior) AFAIK .

Stéphane Chazelas
fuente
1
¿Hay algún truco similar para bash?
Martin Vegter