Парсинг вывода ls
не надежно.
Вместо этого используйте find
определять местоположение каталогов и sort
заказать им меткой времени. Например:
IFS= read -r -d $'\0' line < <(find . -maxdepth 1 -type d -printf '%T@ %p\0' \
2>/dev/null | sort -z -n)
file="${line#* }"
# do something with $file here
Во-первых, find
команды определяют местоположение всех каталогов в текущем каталоге (.
), но не в подкаталогах текущего каталога (-maxdepth 1
), затем распечатывает:
Метка времени важна. %T@
спецификатор формата для -printf
ломается в T
, который указывает "Время последнего изменения" файла (mtime) и @
, который указывает "На секунды с 1970", включая доли секунды.
Пространство является просто произвольным разделителем. Полный путь в файл - то, так, чтобы мы могли обратиться к нему позже, и Нулевой символ является разделителем, потому что это - запрещенный символ в имени файла и таким образом сообщает нам наверняка, что мы достигли конца пути к файлу.
Я включал 2>/dev/null
так, чтобы файлы, которые у пользователя нет разрешения получить доступ, были исключены, но сообщения об ошибках о них исключаемый подавлены.
Результат find
команда является списком всех каталогов в текущем каталоге. Список передается по каналу к sort
который проинструктирован к:
-z
Рассматривайте ПУСТОЙ УКАЗАТЕЛЬ как символ разделителя строки вместо новой строки.-n
Отсортируйте численноС тех пор seconds-1970 всегда повышается, мы хотим файл, метка времени которого была самым маленьким количеством. Первый результат sort
будет строка, содержащая самую маленькую пронумерованную метку времени. Все, что остается, должно извлечь имя файла.
Результаты find
, sort
конвейер передается через замену процесса read
, где это читается, как будто это был файл на stdin.
В контексте read
мы устанавливаем IFS
переменная ни к чему, что означает, что пробел не будет неуместно интерпретироваться как разделитель. read
сказан -r
, который отключает расширение Escape, и -d $'\0'
, который делает ПУСТОЙ УКАЗАТЕЛЬ разделителя конца строки, соответствуя ouput от нашего find
, sort
конвейер.
Первый блок данных, которые представляют самый старый путь к каталогу, которому предшествует его метка времени и пространство, читается в переменную line
. Затем, замена параметра используется с выражением #*
, который просто заменяет все символы с начала строки до первого пространства, включая пространство, ни с чем. Это снимает изоляцию с метки времени модификации, оставляя только полный путь файлу.
В этой точке имя файла хранится в $file
и можно сделать что-либо, включая что Вы любите с ним, rm -rf "$file"
.
Нет. Более простыми путями является багги.
Если Вы используете ls -t
и канал к tail
Вы повредитесь на файлах с новыми строками в именах файлов. Если Вы rm $(anything)
затем файлы с пробелом на имя вызовут поломку. Если Вы rm "$(anything)"
затем файлы с запаздывающими новыми строками на имя вызовут поломку.
Возможно, в конкретных случаях Вы знаете наверняка, что более простой путь достаточен, но Вы никогда не должны писать предположения как этот в к сценариям, если можно постараться не делать так.
#!/usr/bin/env bash
dir="$1"
min_dirs=3
[[ $(find "$dir" -maxdepth 1 -type d | wc -l) -ge $min_dirs ]] &&
IFS= read -r -d $'\0' line < <(find "$dir" -maxdepth 1 -printf '%T@ %p\0' 2>/dev/null | sort -z -n)
file="${line#* }"
ls -lLd "$file"
Больше полного решения проблемы, так как это проверяет dir, рассчитывает сначала.
В Debian-полученных дистрибутивах консоль и X ключевых отображений теперь оба настраиваются в/etc/default/keyboard. См. http://wiki.debian.org/Keyboard.
Прежде чем это и X и консольные отображения ключа было настроено отдельно каждый с его собственным соответствующим набором утилит и конфигурационных файлов. См. http://www.tldp.org/HOWTO/text/Keyboard-and-Console-HOWTO.