ls -l --group-directoryies-first (действует также на символические ссылки)

9

lsопция --group-directories-firstзаставляет каталоги быть перечисленными сверху, что делает вывод lsкрасивым и чистым:

ls -l --group-directories-first

Тем не менее, это не действует symlinks, которые на самом деле относятся symlinksк каталогам. Есть возможность использовать

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

который перечислит оба вида каталогов сверху, но не будет различать надлежащий каталог и каталог с символическими ссылками, что опять-таки сбивает с толку.

Можно ли lsотображать каталоги с символическими ссылками сверху, при этом отличая их от обычных каталогов?

РЕДАКТИРОВАТЬ: я использую bash.

Мартин Вегтер
источник
Это своеобразное поведение со стороны ls. Согласно stat()системному вызову, символическая ссылка на каталог все еще является каталогом ( S_ISDIR(st_mode)вернет true). Доказывает, lsчто символические ссылки, прежде чем он это проверяет.
Златовласка
2
@goldilocks, нет, lsделает lstat()readlinkдля символических ссылок), если вы не используете -Lопцию (в этом случае она использует stat())
Стефан Шазелас
@StephaneChazelas: Хмм, живи и учись. Я думал, что S_ISLNK(st_mode)также вернул истину через stat(), но это не так - он делает это только через lstat(). Также, что ISLNK не возвращает true через stat, даже если ссылка является ссылкой на ссылку. Это означает, что ISLNKэто никогда не вернет истину через стат, хотя это не определено ...
Златовласка
@goldilocks, statдает вам свойства файла в конце символической ссылки. Если это не существует или недоступно, statвозвращается ENOENT, поэтому то, что возвращается, statникогда не будет символической ссылкой. stat()никогда не скажет вам ничего о символических ссылках, точно так же, как openникогда не откроет символическую ссылку, или chmod()не изменит разрешения символической ссылки ... и т. д.
Стефан Шазелас

Ответы:

5

Нет, но если zshвы используете , вы можете сделать:

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

Вы также можете определить порядковый порядок сортировки, например:

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

и используйте это как:

ls -ldU -- *(o+dir1st)

Таким образом, вы можете использовать его для других команд, отличных от lsили lsс другими параметрами, или для других шаблонов, таких как:

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

или:

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

Если вам нужно использовать bash, эквивалент будет выглядеть так:

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

bashне имеет спецификаторов глобализации или какого-либо способа повлиять на порядок сортировки глобусов, или какого-либо способа поворачивать nullglob для каждого глобуса, или не иметь локального контекста для параметров (кроме запуска подоболочки, следовательно, ()вместо {}вышеупомянутого) AFAIK ,

Стефан Шазелас
источник
1
Есть ли подобный трюк для bash?
Мартин Вегтер