man bash
говорит:
The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and pathname expansion [...] After these expansions are performed, quote characters present in the original word are removed unless they have been quoted themselves (quote removal).
Таким образом, удаляются только кавычки исходного слова . Но эти ваши цитаты появляются только после расширения и не удаляются.
В данном случае вы можете их не указывать, так как ваши имена файлов не нуждаются в кавычках, но вы столкнетесь с проблемами с именами файлов с пробелами или другими специальными символами. И ни кавычки, ни обратные слэши вам не помогут, так как на данном этапе обработки они не считаются кавычками.
Изменить для обслуживания «одношагового» запроса:
Но что, если у вас есть куча файлов с пробелами, например foo file foo
и bar file bar
, и вы хотите cat
некоторые из них?
Ваша командная строка будет выглядеть так:
cat "foo file foo" "bar file bar"
но если их больше, вам нужно написать сценарий.
echo -n cat; for name in foo bar; do echo -n \ \"$name file $name\"; done
Выведет именно ту строку, которую вы вводите, но
$(echo -n cat; for name in foo bar; do echo -n \ \"$name file $name\"; done)
завершится ошибкой по причине, описанной выше. Заключение всего в двойные кавычки (, как помогло в вашем gimp
случае ), также не сработает, потому что новую команду нужно отделять словами, а не внутри кавычек.
Так что же сделать, чтобы цитирование работало так, как если бы оно вводилось непосредственно в командной строке? Передайте вашу строку как команду оболочке:
bash -c "$(echo -n cat; for name in foo bar; do echo -n \ \"$name file $name\"; done)"
Это должно быть наиболее общим подходом для одного -лайнера, выполняющего сгенерированную команду.