Как использовать переменную (строку) Bash, содержащую кавычки в команде?


45

Неудачный, упрощенный пример:

FLAGS='--archive --exclude="foo bar.txt"'
rsync $FLAGS dir1 dir2

Мне нужно включить кавычки, как если бы команда была такая:

rsync --archive --exclude="foo bar.txt" dir1 dir2

Ответы:


56

Краткий ответ: см. BashFAQ # 50 («Я пытаюсь поместить команду в переменную, но сложные случаи всегда терпят неудачу!»).

Длинный ответ: Поместить команды (или части команд) в переменные, а затем вернуть их нетронутыми, сложно. Когда оболочка раскрывает переменную в командной строке, если переменная заключена в двойные кавычки, она не анализируется; если это не было в кавычках, пробелы в нем анализируются как разрывы аргументов, но кавычки и escape не анализируются. В любом случае, размещение кавычек в значении переменной ничего не дает.

Обычно лучший способ сделать это - использовать массив вместо простой текстовой переменной:

FLAGS=(--archive --exclude="foo bar.txt")
rsync "${FLAGS[@]}" dir1 dir2

Святой Иезус, это работает!
Славомир


-2

Я не вижу проблемы:

$ FLAGS='--archive --exclude="foo bar.txt"'
$ echo $FLAGS
--archive --exclude="foo bar.txt"

Может быть, вам нужно снова процитировать значение:

$ rsync "$FLAGS" dir1 dir2

5
echoне показывает, что вы думаете. Попытайтесь printargs() { printf "'%s' " "$@"; echo; }; printargs $FLAGS; printargs "$FLAGS"понять, почему ни один из этих вариантов не работает.
Гордон Дэвиссон
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.