Я пишу сценарий для резервного копирования, как это:Как передать переменное количество параметров команде оболочки?
backup.sh:
dir="$1"
mode="$2"
delta="$3"
for file in "$dir/backup."*".$mode.tar.gz"; do
[ "$file" -nt "$ref" ] && ref="$file"
done
if [ "$delta" = "true" ]; then
delta_cmd=-N "'$ref'"
fi
backup_file="$dir/backup.$(date +%Y%m%d-%H%M%S).$mode.tar.gz"
case "$mode" in
config)
tar -cpzvf "$backup_file" $delta_cmd \
/etc \
/usr/local
;;
# still other modes here...
esac
Я хочу передать один переменный $delta_cmd
в команду дегтя, так что гудроны все файлы или только дельта файлы с момента последнего резервного копирования в зависимости от значения $delta
.
Приведенный выше код создает сообщение об ошибке и не деформирует дельта-файлы правильно, если для параметра $delta
установлено значение true. Как это исправить?
P.S: Сценарий лучше совместим с POSIX.
Это * возможно * сделать этот POSIX совместимым, но только путем внедрения уязвимостей безопасности (с использованием 'eval') или перезаписывания' $ @ '(что вполне * не * совместимо с использованием строки' delta_cmd'), что означает инкапсуляцию t он код в функции, если вы не хотите переопределять глобальное значение сценария для этого массива. См. BashFAQ # 50 для описания того, почему строковые переменные (в отличие от массивов) нельзя безопасно использовать для хранения списков или команд аргументов по адресу http://mywiki.wooledge.org/BashFAQ/050 –
Не могли бы вы немного объяснить больше о переписывании '$ @' способом? –
Добавлен ответ. Кстати, в этом коде есть много чего, что можно было бы сократить, чтобы создать правильный MCVE (** минимальный **, полный, проверенный пример, см. Http://stackoverflow.com/help/mcve) - I ' я очень сомневаюсь включить контент в свой ответ, который включает в себя такие плохие практики, как синтаксический анализ 'ls', но замена лучшей практики для этого кода также несколько выходит за рамки рассматриваемого вопроса. –