ls -l --group-directory-first (também atua nos links simbólicos)

9

lsA opção --group-directories-firstfaz com que os diretórios sejam listados na parte superior, o que torna a saída lsagradável e limpa:

ls -l --group-directories-first

No entanto, ele não age sobre symlinks, que são, na verdade symlinksaos diretórios. Existe a possibilidade de usar

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

que listará ambos os tipos de diretórios na parte superior, mas não fará distinção entre o diretório apropriado e o diretório vinculado, o que é novamente confuso.

Pode lsexibir diretórios com links simbólicos na parte superior, mantendo-os distintos dos diretórios regulares?

EDIT: eu estou usando bash.

Martin Vegter
fonte
Esse é um comportamento idiossincrático da parte de ls. De acordo com a stat()chamada do sistema, um link simbólico para um diretório ainda é um diretório ( S_ISDIR(st_mode)retornará verdadeiro). Evidencialmente lsdesconta os links simbólicos antes de verificar isso.
Goldilocks
2
@goldilocks, não, lsfaz lstat()(e readlinkpara links simbólicos) a menos que você use a -Lopção (caso em que ele usa stat())
Stéphane Chazelas
@StephaneChazelas: Hmm, viva e aprenda. Eu pensava que isso S_ISLNK(st_mode)também retornava verdadeiro via stat(), mas isso não acontece - apenas o faz via lstat(). Além disso, o ISLNK não retorna true via stat, mesmo que o link seja um link para um link. O que significa que ISLNKtalvez nunca retorna true via stat, apesar de que é tipo de não especificada ...
Goldilocks
@goldilocks, statfornece as propriedades do arquivo no final dos links simbólicos. Se isso não existir ou não estiver acessível, statretornará ENOENT; portanto, o que é retornado statnunca será um link simbólico. stat()nunca vai dizer nada sobre links simbólicos, como opennunca vai abrir o link simbólico, ou chmod()não vai alterar as permissões de um link simbólico ... etc.
Stéphane Chazelas

Respostas:

5

Não, mas se estiver usando zsh, você pode fazer:

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

Você também pode definir uma ordem de classificação globbing como:

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

e use-o como:

ls -ldU -- *(o+dir1st)

Dessa forma, você pode usá-lo para outros comandos que não sejam lsou com lsopções diferentes, ou para padrões diferentes, como:

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

ou:

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

Se você precisar usar bash, o equivalente seria o seguinte:

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 -- "$@"
)

bashnão possui qualificadores de globbing ou qualquer maneira de afetar a ordem de classificação dos globs, ou qualquer maneira de ativar o nullglob em uma base por glob ou ter contexto local para opções (exceto iniciar um subshell, portanto, em ()vez de {}acima) AFAIK .

Stéphane Chazelas
fonte
1
Existe algum truque semelhante para bash?
Martin Vegter