Назад | Перейти на главную страницу

выполнение строки debian bash / sh

Я застрял здесь с этим фрагментом кода

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 разберемся позже;))