Персонажи, случайно исчезающие из вывода «find»

Получение полного имени первого файла:

shopt -s nullglob
printf '%s\000' * | grep -z -m 1 '^..*$'
printf '%s\000' * | ( IFS="" read -r -d "" var; printf '%s\n' "$var" )
1
05.03.2019, 09:52
3 ответа

Одно из возможных объяснений состоит в том, что одна команда в цикле читает из stdin (, который в данном случае является тем же потоком, который readпредназначен для чтения из ). Как вы выяснили , это будет ffmpeg, который позволяет пользователю управлять кодировкой с помощью клавиатуры (, если вы не передадите опцию -nostdin), следовательно, чтение из стандартного ввода в получить пользовательский ввод.

Это одна из нескольких проблем, связанных с зацикливанием вывода find.

Используйте:

find... -exec sh -c '
  for mp4file do
   ...
  done' sh {} +

стандартный синтаксис (, в котором stdin shи ffmpegне изменяется ), или один из других подходов, описанных в Почему зацикливание вывода find является плохой практикой? , что также устранит проблемы с именами файлов, которые содержат символы новой строки (или $IFSсодержат 4с вашим подходом ).

2
27.01.2020, 23:22

[не совсем ответ; в комментариях ничего форматировать нельзя]

Обратите внимание, что в ненайденных файлах начальные 6, 7 или 8 символов из /mnt/zbigобрезаны:

/mnt/zbig/media/Movies/Edición/@video-remux/8 El hijo de Randal.mp4  [ok]
...
big/media/Movies/Edición/@video-remux/19 La cueva de las flores.mp4  [error]
...
g/media/Movies/Edición/@video-remux/21 La fiesta de la Luna.mp4 [error]

Я сильно подозреваю, что в bashесть ошибка с многобайтовой кодировкой/локалью; попробуйте запустить свой скрипт с помощью LC_ALL=C your_script.shи посмотрите, есть ли разница. Поскольку ошибка не связана с ffmpegили другими вещами, а только с read, вы, вероятно, можете сократить свой тестовый пример до

find. -type f -name "*.mp4"... | while read -r f; do
   ls "$f"
done > /dev/null

Также укажите (в своем вопросе )ваш дистрибутив и bashверсию.

Конечно, использовать find | read -rужасно, но суть вопроса не в этом, верно? И если это не какая-то простая ошибка пользователя, ошибка остается ошибкой, независимо от того, образцовый код или нет.

0
27.01.2020, 23:22

Наконец-то нашел причину, по которой мой исходный код не работал. Проблема была ffmpegи как она взаимодействует с stdin. Подробнее об этом можно прочитать здесь:

Найдено 3 возможных решения:

  1. Используйте синтаксис оболочки, предложенный ранее @StéphaneChazelas
  2. Перенаправить стандартный ввод с помощью< /dev/null
  3. Используйте ffmpeg с опцией-nostdin
1
27.01.2020, 23:22

Теги

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