Я застрял здесь с этим фрагментом кода
user@server:~$ TEST="ssh rsync@otherserver.example.org 'date; hostname -A; uname -a'"
user@server:~$ $TEST
bash: date; hostname -A; uname -a: Command not found.
Я хочу использовать это внутри сценария оболочки и не знаю, в чем проблема. Обе системы - это debian wheezy,
но если выполнить команду напрямую:
user@server:~$ ssh rsync@otherserver.example.org 'date; hostname -A; uname -a'
Fre Aug 23 20:02:55 CEST 2013
otherserver.example.org
Linux otherserver 3.2.0-4-amd64 #1 SMP Debian 3.2.46-1 x86_64 GNU/Linux
Так что тут такого ???? Я упускаю что-то очень тривиальное, но не могу понять ... Пожалуйста, помогите ...
Идея заключается в том, что я создаю длинную строку внутри сценария и выполняю ее удаленно в одном сеансе SSH (переименование всех снимков zfs в строке №0 становится №1 и т. Д.)
Но он не работает, я хочу, чтобы он работал ...
ИЗМЕНИТЬ / ОБНОВИТЬ: Обновлены примеры для лучшего понимания моего вопроса (from 'date; date; date' TO 'date; hostname -A; uname -a')
Спасибо за все ответы. Сначала eval работает, но, как упоминалось пользователями, кажется, что он устарел. Так что моя работа - снова выяснить, как это изменить.
Струнная ведьма, которую нужно построить, выглядит примерно так:
echo "Rearanging snapshots..."
last_backup=7
first_backup=0
RENAME_STRING="'sudo zfs destroy $BACKUP_DATASTORE@n.$last_backup; "
while [ $last_backup -gt $first_backup ]
do
RENAME_STRING=$RENAME_STRING"sudo zfs rename $BACKUP_DATASTORE@n.$(($last_backup - 1)) $BACKUP_DATASTORE@n.$last_backup"
if [ $(($last_backup - 1 )) -gt $first_backup ]
then
RENAME_STRING=$RENAME_STRING"; "
else
RENAME_STRING=$RENAME_STRING"'"
fi
last_backup=$(($last_backup - 1 ))
done
#CURRENTLY SOLVED WITH EVAL as this one doesn't work...
#remote_cmd=(/usr/bin/ssh "$BACKUP_USER@$HOST_TO" "$RENAME_STRING")
#"${remote_cmd[@]}"
eval /usr/bin/ssh $BACKUP_USER@$HOST_TO $RENAME_STRING
Так, может быть, у вас, ребята, будет более элегантный способ решить эту проблему?
РЕДАКТИРОВАТЬ2:
Этот вывод "ОК"? (Хорошо, как в средствах НЕ устарело, и с ними можно работать?
user@server:~$ TEST="date ; hostname -A ; uname -a"
user@server:~$ ssh rsync@otherserver.example.org <<< "$(printf '%s ' $TEST)"
Pseudo-terminal will not be allocated because stdin is not a terminal.
Linux otherserver 3.2.0-4-amd64 #1 SMP Debian 3.2.46-1 x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Fre Aug 23 20:13:53 CEST 2013
otherserver.example.org
Linux otherserver 3.2.0-4-amd64 #1 SMP Debian 3.2.46-1 x86_64 GNU/Linux
EDI3: Обновлен / улучшен (?), В то время как eval цикла все еще используется как <<< не будет работать в скрипте ...
Предлагаемый способ удаленного выполнения локальных команд через ssh - не использовать eval. Это не приветствуется. Поскольку вы сохраняете всю строку в переменной, вместо этого вы можете
mydate=$(date; date; date);
ssh rsync@example.org bash <<< "$(printf 'echo %q ' "$mydate")"
Eval следует использовать только в устаревших системах, которые не предоставляют безопасных инструментов, таких как пример, который я вам показываю.
Это дает точно такой же результат, как и при выполнении этих команд с помощью интерактивной оболочки.
Надеюсь, это даст вам хоть какие-то идеи.
ОБНОВЛЕНИЕ, чтобы продемонстрировать, как команды могут выполняться удаленно, без определения локальной переменной.
ssh rsync@example.com bash <<< "$(printf '%s ' "whoami && ps aux")"
Попробуй это:
user@server:~$ remote_cmd=(ssh rsync@otherserver.example.org 'date; hostname -A; uname -a')
user@server:~$ "${remote_cmd[@]}"
Он создает массив и выполняет его, как предложено в BashFAQ / 050 пункт 3.
Нет смысла составлять такую длинную строку команд для запуска через SSH. Просто создайте постоянный сценарий на удаленном хосте под названием /usr/local/sbin/rotate_backups
и назови это с ssh $USER@$HOST 'sudo /usr/local/sbin/rotate_backups'
.
Если бы вы спрашивали об этом на «Unix и Linux» StackExchange, тогда это может быть интересный вопрос. Однако, как системный администратор, вашими целями должны быть удобство обслуживания и безопасность. Если у вас возникнут проблемы с пониманием сценария, ваши коллеги и преемники проклянут вас.
Попробуйте встроенную оболочку / bash оценка команда:
$ help eval
eval: eval [arg ...]
Execute arguments as a shell command.
Combine ARGs into a single string, use the result as input to the shell,
and execute the resulting commands.
Exit Status:
Returns exit status of command or success if command is null.
НАЙДЕНА ПРОБЛЕМА
Я начал свою длинную струну с одной '
и endet с одним '
СЕЙЧАС я сохраняю все одинарные кавычки ('
) сам создаю строку и добавляю двойные кавычки в конце, ВСЕ РАБОТАЕТ!
#!/bin/sh
...
#[SOME_CODE_HERE]
...
echo "Rearanging snapshots..."
last_backup=7
first_backup=0
RENAME_STRING="sudo zfs destroy $BACKUP_DATASTORE@n.$last_backup; "
while [ $last_backup -gt $first_backup ]
do
RENAME_STRING=$RENAME_STRING"sudo zfs rename $BACKUP_DATASTORE@n.$(($last_backup - 1)) $BACKUP_DATASTORE@n.$last_backup; "
last_backup=$(($last_backup - 1 ))
done
/usr/bin/ssh $BACKUP_USER@$HOST_TO "$RENAME_STRING"
Так может кто-нибудь объяснить мне, почему я не могу установить кавычки внутри моей переменной?
И эта конструкция теперь работает нормально. Спасибо за вашу помощь! Надеюсь, что мой ответ тоже кому-то поможет! (про ALL_CAPITAL разберемся позже;))