У вас есть этот оператор перед вашим циклом for
:
IFS=$'\n'
Это устанавливает ваш внутренний разделитель полей на новые строки вместо того, чтобы по умолчанию совпадать с любым пробелом.Это меняет способ анализа замещаемых параметров.В строке построения команды:
${TOOL} ${OPT1} ${file} -o ${OUTS}${file} ${OPT2}
произойдет следующее: каждое из этих ${variable}
выражений будет расширено, а затем оболочка попытается разбить их на \n
, а не на пробел, как выбудет нормально ожидать.Это даст вам результат, аналогичный приведенному ниже (если только одна из этих переменных не содержит символ новой строки):
"${TOOL}" "${OPT1}" "${file}" -o "${OUTS}${file}" "${OPT2}"
Здесь вы можете видеть, что вы передаете всю строку ${OPT2}
как однупараметр, вместо того, чтобы позволить Bash разделить его на пробелы и передать каждый флаг в отдельности.mencoder
затем запутывается в этом огромном параметре, с которым он не знает, что делать.Конечно, поскольку все пробелы все еще есть, они будут распечатаны командой echo
и будут нормально работать в оболочке, в которой $IFS
не был сброшен.
Вы можете продемонстрировать этоэффект довольно легко, определяя простую функцию, которая будет печатать каждый из своих аргументов в отдельной строке:
$ print_args() { for arg; do echo $arg; done }
$ foo="1 2"
$ print_args ${foo} ${foo}
1
2
1
2
$ IFS=$'\n'
$ print_args ${foo} ${foo}
1 2
1 2
Я бы рекомендовал не использовать трюк $IFS
для вашего цикла for
.Вместо этого вы можете использовать while read file
для итерации по каждой строке ввода.Я бы также рекомендовал не использовать printf "%q"
для экранирования пробелов, а вместо этого просто заключить аргумент в mencoder
, который передаст все это как один аргумент.Обратите внимание, что я цитирую ${file}
и ${OUTS}${file}
, чтобы убедиться, что они передаются в каждом из них как один аргумент, но не цитирую ${OPT1}
и ${OPT2}
, чтобы их можно было проанализировать как отдельные аргументыракушка.
find . -name "*.*" -type f | sed 's!.*/!!' | while read -r file
do
"${TOOL}" ${OPT1} "${file}" -o "${OUTS}${file}" ${OPT2}
done
Кстати, я бы рекомендовал использовать $()
для подстановки команд, а не ``
;Есть много причин , почему это предпочтительнее, таких как читабельность, более разумное цитирование и экранирование правил внутри него, а также возможность вложения нескольких уровней подстановки команд.И проблемы, на которые указывают Джонатан и Уэс, хорошо отметить, хотя они не являются причиной вашей непосредственной проблемы.