Сценарий bash имеет следующую строку
rsync $OPTS $BACKDIR $USER@$DEST:$DESTDIR
но один из вариантов rsh='ssh -p2222'
Он жалуется:
rsync: -p2222': unknown option
rsync error: syntax or usage error (code 1) at main.c(1425) [client=3.0.7]
Но когда я меняю сценарий на:
echo rsync $OPTS $BACKDIR $USER@$DEST:$DESTDIR
и вручную запустите напечатанную команду, она работает.
пожалуйста, порекомендуйте
Краткий ответ: см. BashFAQ # 50.
Длинный ответ: сложно поместить команды (или части команд) в переменные, а затем вернуть их в неизменном виде. Когда оболочка расширяет переменную в командной строке, если переменная была заключена в двойные кавычки, она не анализируется (см. Ответ @Dennis Williamson); если он не был заключен в кавычки, пробелы в нем анализируются как разрывы аргументов, но кавычки и escape-символы не анализируются (вот почему вы получили ошибку о буквальном значке кавычек в одном из аргументов для rsync). В любом случае помещение в кавычки значения переменной не дает ничего полезного.
Однако есть несколько способов исправить ваш скрипт, в зависимости от сложности OPTS:
Если --rsh - единственное, что есть в OPTS, заключите его в двойные кавычки (как в ответе Денниса Уильямсона):
OPTS='--rsh=ssh -p2222'
rsync "$OPTS" "$BACKDIR" "$USER@$DEST:$DESTDIR"
(Обратите внимание на двойные кавычки вокруг других аргументов: это необходимо для предотвращения неправильного анализа, если они содержат пробелы, и, как правило, это хорошая гигиена сценариев.)
Если содержимое OPTS постоянно (или, по крайней мере, часть --rsh), не пытайтесь поместить его в переменную, просто используйте ее напрямую:
rsync --rsh='ssh -p2222' $RESTOFOPTS "$BACKDIR" "$USER@$DEST:$DESTDIR"
Если ни один из этих простых случаев не подходит, используйте массив вместо простой переменной:
OPTS=(-x --delete --inplace)
if [[ "$rsync_version" == 2.* ]]; then
OPTS+=(-aE)
else
OPTS+=(-aNHX)
fi
if [[ -n "$using_rsh" ]]; then
OPTS+=('--rsh=ssh -p2222')
fi
rsync "${OPTS[@]}" "$BACKDIR" "$USER@$DEST:$DESTDIR"
Чтобы сохранить кавычки и пробелы в переменной, вам нужно заключить переменную в кавычки, когда на нее ссылаются:
rsync "$OPTS" "$BACKDIR" "$USER@$DEST:$DESTDIR"
Я думаю твой rsh
параметр следует использовать с rsync -e
(соотв. --rsh
), чтобы rsync знал, что нужно использовать настраиваемый порт для ssh-соединения. Ваша команда выглядит так:
ssh -some -opts --rsh="ssh -p222" fromdir/ user@host:/todir
Может случиться так, что кавычки вокруг части 'ssh -p222' просто отсутствуют при выполнении rsync. Вы можете попробовать определить rsh
вместо этой переменной:
rsh='"ssh -p222"'
так что во время выполнения он оценивается как «ssh -p222» (буквально, включая двойные кавычки).
Один из вариантов - удалить "пробел" из $ IFS в вашем скрипте:
#!/bin/bash
IFS=$'\n\t'
...
rsync $OPTS $BACKDIR $USER@$DEST:$DESTDIR
В этом случае Bash будет вести себя так, как ожидает большинство программистов, поскольку пробелы больше не будут использоваться в качестве разделителей полей внутри переменных.