Как я передаю переменную со своего локального сервера на удаленный сервер?

Это зависит полностью от Ваших реальных потребностей. Обновления часто повреждают по крайней мере некоторые части системы, поэтому если Вы не готовы провести некоторое время, настраивая обновленную систему, остаться с текущей, пока Вы получаете обновления системы защиты, и это удовлетворяет Вашим потребностям. Что касается увеличения производительности, не ожидайте увеличение порядков величины, это будет больше на уровне единственных процентов. Обычно может даже быть отбрасывание производительности в хорошо настроенной системе, особенно после того как Вы изменяете ядро.

2
03.06.2014, 02:36
6 ответов

переменные не расширяются между одинарными кавычками.

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

sshpass -p "password" \
  ssh username@74.11.11.11 "su -lc \"cp -r $location2 $location1\";"

или закройте одинарные кавычки и откройте их снова:

sshpass -p "password" \
  ssh username@74.11.11.11 'su -lc "cp -r '$location2' '$location1'";'

bash выполняет конкатенацию строк автоматически.

примечание: не проверено. может неточно работать, если $locationX содержит пробелы или другие странные символы.

5
27.01.2020, 21:50

Переменная оболочки - это всего лишь переменная оболочки. Команда ssh или оболочка, запущенная sshd на удаленном хосте, не имеют возможности получить доступ к этой переменной клиентской оболочки.

Экспортированные переменные оболочки передаются как переменные среды выполняемым командам.Итак, если вы экспортировали location1 , он будет передан как переменная среды в ssh . Если вы использовали конфигурационную директиву SendEnv ssh (через -o или ~ / .ssh / config или / etc / ssh / ssh_config] ...), ssh попытается отправить его на sshd на удаленном хосте.

Однако для того, чтобы это работало, sshd должна иметь конфигурационную директиву AcceptEnv , которая позволяет получать эту переменную. Однако, как правило, это не так по соображениям безопасности.

Однако многие развертывания ssh / sshd по умолчанию позволяют передавать переменные, имя которых начинается с LC_ (для локализации). Таким образом, вы можете использовать это с помощью:

LC_location1=$location1 LC_location2=$location2 ssh host 
    'su -lc '\''cp -r -- "$LC_location2" "$LC_location1"'\''

В качестве альтернативы вы можете заставить локальную оболочку расширять переменные в командной строке, которая передается удаленной оболочке:

ssh host "su -lc 'cp -r -- $location2 $location1'"

Но это эквивалентно выполнению:

eval eval "cp -r -- $location2 $location1"

Это те переменные не передаются в качестве аргументов в cp , они интерпретируются (дважды) как оболочка (оболочка входа удаленного пользователя и sh , запущенная su ) код, поэтому, если $ location1 будет, например, / где-то; rm -rf / , это будет иметь драматические последствия.

Правильный способ - это правильно экранировать их для удаленной оболочки.Из-за двух уровней оболочки вам нужно дважды избегать одинарных кавычек (здесь используется синтаксис ksh93 / bash / zsh ):

escaped_location1=\'${location1//\'/\'\\\'\'}\'
escaped_location1=${escaped_location1//\'/\'\\\'\'}
escaped_location2=\'${location2//\'/\'\\\'\'}\'
escaped_location2=${escaped_location2//\'/\'\\\'\'}
ssh host "su -lc 'cp -r -- $escaped_location2 $escaped_location1'"

Это предполагает оболочка входа в систему удаленного пользователя похожа на Bourne.

5
27.01.2020, 21:50

Вы также можете оказаться в следующей ситуации: Вы хотите запустить на удаленной машине программу, которую нельзя изменить и которая считывает переменную $FOO. Таким образом, вам нужно, чтобы $FOO было установлено на удаленной машине.

Если $FOO не содержит никаких специальных shell-символов, вы можете сделать:

ssh server FOO=$FOO the_program

Если $FOO содержит специальные shell-символы, то вам нужно процитировать их, и это может быть довольно сложно, и если $FOO содержит \n в два раза больше, то так и есть. Это все равно можно сделать, если вы сами установите $FOO. Но если $FOO задан пользователем, вам понадобится программа, которая процитирует его для вас. Одним из решений является (ab)использование GNU Parallel:

export FOO
parallel -N0 -S server --env FOO the_program ::: ""

GNU Parallel умеет передавать переменные со всевозможными специальными символами. Например:

FOO='* < " > $ ! # @ ) ( ] [ } { | & % \ ''here is a quoted newline
more of FOO'"'"'s content'
export FOO
parallel -N0 -S localhost --env FOO echo '"$FOO"' ::: ""
0
27.01.2020, 21:50

Просто напишите переменную или данные, необходимые в локальный файл, а затем в скрипте запустите команду SCP, чтобы отправить файл на удаленный сервер. На удаленном сервере есть сценарий, который периодически проверю (через CRON) для файла и прочитать его содержимое и делать все, что вы хотите сделать.

-1
27.01.2020, 21:50

Взгляните на этот сценарий, который я написал для обновления нашей службы.

PROJ = $ 2 будет передано в удаленную среду env.

function update-env () {
    env=$1
    proj=$2

    # script for update test env
    ssh -A root@$2.$1.test.com PROJ=$2 'bash -s' <<'ENDSSH'
        # commands to run on remote host
        su gmuser
        cd /srv/apps/$PROJ
        /usr/bin/git pull
        exit
        supervisorctl restart $PROJ
    ENDSSH
}
0
27.01.2020, 21:50

В дополнение к ответу lesmana: вы должны привести переменные в его втором примере.

sshpass -p "password" \
  ssh username@74.11.11.11 'su -lc "cp -r '\\\"$location2\\\"' '\\\"$location1\\\"'";'
0
27.01.2020, 21:50

Теги

Похожие вопросы