Проблема автоматизации сценария Bash

Я вынимаю это из контекста, но этот бит моего сценария не выполняется правильно:

latest=$(ls ~/Videos/ -t | head -n 1 | sed 's/ /\\ /g')
mpv ~/Videos/$latest

Я пытаюсь автоматически играть последний файл, добавленный к моему каталогу Videos. Следующая ошибка происходит:

Error parsing option t (option not found)
Setting command line option '--t=' failed.

Exiting... (Fatal error)
0
задан 18 July 2016 в 02:39

1 ответ

Парсинг вывода ls обычно плохая идея. Выполнение поэтому, когда тот вывод является списком видеофайлов, является абсолютно ужасной идеей. Видеофайлы будут почти наверняка содержать пробелы и другие странные символы, которые, очень вероятно, вызовут проблемы. Вот более безопасная альтернатива, которая делает то же самое:

latest="$(stat --printf '%Y\t%n\0' * | sort -zk1 | tail -zn1 | cut -f2-)"
mpv "$latest"

Или, если Ваш tail не имеет -z флаг:

latest="$(stat --printf '%Y\t%n\0' * | sort -rzk1 | awk -F'\t' -vRS='\0' '{print $2; exit}'

Или

latest="$(stat --printf '%Y\t%n\0' * | sort -rzk1 | perl -00pe 's/^\d+\s+(.*?)\0.*/$1/s')"

Отметьте заключение в кавычки. Необходимо всегда заключать переменные в кавычки, если Вы не абсолютно уверены, что заключение в кавычки повредит что-то. Это решение использование stat распечатать дату модификации файла (%Y), вкладка (\t), имя файла (%n) и Нулевой символ (\0). Это питается к виду который виды на 1-м поле (-k1), дата и ожидает разделенный от пустого указателя вход (-z). Через это затем проходят tail получить последнее (-n1) разделенный от пустого указателя (-z) строка и, наконец, cut удаляет дату, оставляя только имя файла. Это гарантирует, что можно иметь дело с произвольными файлами, даже любой с новыми строками на их имена.


Ошибку, которую Вы видите, трудно диагностировать, не зная названия файлов в ~/Videos. Основной вопрос - то, что Вы не заключаете имя переменной в кавычки, и так как, кажется, существует файл с --t, это взято в качестве аргумента. Если Вы знаете, что Ваши имена файлов никогда не будут содержать новые строки, Вы могли бы также сделать:

latest="$(ls ~/Videos/ -t | head -n 1)"
mpv ~/Videos/"$latest"

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

0
ответ дан 28 September 2019 в 23:04

Другие вопросы по тегам:

Похожие вопросы: