Как добавить аргументы в цикле ZSH, а затем передать их команде?

Рассматривали ли вы хронический из moreutils . Я думаю, это именно то, что вам нужно:

chronic runs a command, and arranges for its standard out and standard error to only be displayed if the command fails (exits nonzero or crashes). If the command succeeds, any extraneous output will be hidden.

В последних версиях есть переключатель -e, который также показывает полный вывод, если что-то было записано в stderr.

2
07.04.2020, 21:19
1 ответ

У меня нет mkvmergeдля тестирования, но я почти уверен, что проблема заключается в том, как вы цитируете элементы при построении массива. Когда вы делаете что-то вроде

audioargs=("-o./output/${video} --language 0:eng ${video}")

Двойные -кавычки сообщают оболочке, что все это должно рассматриваться как одна длинная строка, поэтому она сохраняется как один элемент в массиве и, следовательно, передается в mkvmergeкак один аргумент, содержащий пробелы, а не ряд аргументов.

Обратите внимание, что echoскрывает различие между пробелом внутри аргумента и пробелом между аргументами, что вводит в заблуждение для подобных вещей. Помещение set -xперед командой должно прояснить, что на самом деле происходит. С вашими примерами имен файлов set -xпоказывает, что выполняется:

echo '-o./output/clip2.mkv --language 0:eng clip2.mkv' '--language 0:ger./ger/clip2.mka' '--language 0:spa./spa/clip2.mka'

Видите длинные одиночные -цитируемые разделы? Вот как он указывает, что это длинные аргументы, содержащие пробелы, а не последовательности отдельных аргументов.

Чтобы решить эту проблему, просто используйте обычные кавычки при построении массива (т. е. такие же кавычки, которые вы использовали бы при передаче аргументов непосредственно в команду ). zsh не разделяет слово -по умолчанию, поэтому технически вам вообще не нужно заключать в кавычки, но я предпочитаю следовать стилю цитирования, совместимому -с -другими оболочками -, поэтому я цитирую все переменные расширения:

#!/bin/zsh

mkdir -p output

for video in *.mkv
do
    audioargs=(-o "./output/${video}" --language 0:eng "./${video}")
    for audiodir in *(/)
        do
            audioargs+=(--language "0:${audiodir}" "./${audiodir}/${video:r}.mka")
        done
    echo "${audioargs[@]}"
done

Что дает этот результат сset -x:

echo -o./output/clip2.mkv --language 0:eng./clip2.mkv --language 0:ger./ger/clip2.mka --language 0:spa./spa/clip2.mka
4
28.04.2021, 23:18

Теги

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