Получение полного имени первого файла:
shopt -s nullglob
printf '%s\000' * | grep -z -m 1 '^..*$'
printf '%s\000' * | ( IFS="" read -r -d "" var; printf '%s\n' "$var" )
Одно из возможных объяснений состоит в том, что одна команда в цикле читает из stdin (, который в данном случае является тем же потоком, который read
предназначен для чтения из ). Как вы выяснили , это будет ffmpeg
, который позволяет пользователю управлять кодировкой с помощью клавиатуры (, если вы не передадите опцию -nostdin
), следовательно, чтение из стандартного ввода в получить пользовательский ввод.
Это одна из нескольких проблем, связанных с зацикливанием вывода find
.
Используйте:
find... -exec sh -c '
for mp4file do
...
done' sh {} +
стандартный синтаксис (, в котором stdin sh
и ffmpeg
не изменяется ), или один из других подходов, описанных в Почему зацикливание вывода find является плохой практикой? , что также устранит проблемы с именами файлов, которые содержат символы новой строки (или $IFS
содержат 4
с вашим подходом ).
[не совсем ответ; в комментариях ничего форматировать нельзя]
Обратите внимание, что в ненайденных файлах начальные 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
ужасно, но суть вопроса не в этом, верно? И если это не какая-то простая ошибка пользователя, ошибка остается ошибкой, независимо от того, образцовый код или нет.
Наконец-то нашел причину, по которой мой исходный код не работал. Проблема была ffmpeg
и как она взаимодействует с stdin
. Подробнее об этом можно прочитать здесь:
Найдено 3 возможных решения:
< /dev/null