S SH Команда в bash - PullRequest
       4

S SH Команда в bash

0 голосов
/ 05 марта 2020

Нужна некоторая помощь по этим командам, которые мы не работаем во время сеанса s sh, но отлично работают при ручном запуске на машине с Ubuntu.

for w in $(echo "/var/asd/dsa/123" | tr "/" " ") ; do echo $w >&2; echo "123"; done

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

var
123
asd
123
dsa
123
123
123

Вместо этого я получаю вот так:

123
123
123
123
<blank space>
<blank space>
<blank space>
<blank space>

Вот полный код:

ssh -o "StrictHostKeyChecking no" -i $PEM_PATH $SERVER_USER@$SERVER_IP << EOF
    for w in $(echo "/var/asd/dsa/123" | tr "/" " ") ; do echo $w >&2; echo "123"; done
EOF

Любая помощь действительно ценятся, спасибо!

Ответы [ 2 ]

0 голосов
/ 05 марта 2020

Есть несколько проблем с вашим подходом:

Ваше здесь c интерполируется локально . Фактическая команда, которую вы выполняете: for w in var asd dsa 123 ; do echo >&2; echo "123"; done

Это можно увидеть с помощью set -x, чтобы включить локальную трассировку, и запустить s sh с cat вместо оболочки входа в систему:

ssh pi cat << EOF
for w in $(echo "/var/asd/dsa/123" | tr "/" " ") ; do echo $w >&2; echo "123"; done
EOF

+ ssh pi cat
++ echo /var/asd/dsa/123
++ tr / ' '
for w in  var asd dsa 123 ; do echo  >&2; echo "123"; done

Как видите, echo /var/asd/dsa/123 и tr / ' ' выполняются локально, а $ w интерполируется в пустую строку.

Возможно, вы хотите использовать одинарные кавычки вокруг EOF:

ssh pi cat << 'EOF'
for w in $(echo "/var/asd/dsa/123" | tr "/" " ") ; do echo $w >&2; echo "123"; done
EOF

+ ssh pi cat
for w in $(echo "/var/asd/dsa/123" | tr "/" " ") ; do echo $w >&2; echo "123"; done

Теперь команда поступает правильно.

Примечание: если вы sh, что $(echo "/var/asd/dsa/123" | tr "/" " ") запускается локально, то вам по крайней мере нужно выйти из $ ш.

ssh pi << EOF
    for w in $(echo "/var/asd/dsa/123" | tr "/" " ") ; do echo \$w >&2; echo "123"; done
EOF

Буферизация испортит порядок . Вот почему ваши пустые строки (напечатанные echo >&2) находятся в конце вашего вывода. Вы можете использовать tee, чтобы «форсировать» буферизацию строки:

ssh -T pi << 'EOF'
for w in $(echo "/var/asd/dsa/123" | tr "/" " ") ; do echo $w >&2; echo "123"; done
EOF

+ ssh -T pi
Linux mserv 3.10.25+ #622 PREEMPT Fri Jan 3 18:41:00 GMT 2014 armv6l
... 

123
123
123
123
var
asd
dsa
123

В сравнении:

ssh pi << 'EOF'
for w in $(echo "/var/asd/dsa/123" | tr "/" " ") ; do echo $w >&2; echo "123"; done 2>&1 | tee
EOF

+ ssh pi
Linux mserv 3.10.25+ #622 PREEMPT Fri Jan 3 18:41:00 GMT 2014 armv6l
...
var
123
asd
123
dsa
123
123
123

(в первом случае сначала печатается STDIN, затем STDERR, во втором, чередуются строки)

Передача команд в s sh и принудительное выполнение оболочки входа Если вы запускаете команды, отправляя их в stdin из s sh, запускается оболочка входа и распечатайте MOTD (в зависимости от конфигурации сервера) и запустите оболочку входа (которая имеет несколько побочных эффектов).

В моем примере Linux mserv 3.10.25+ #622 PREEMPT Fri Jan 3 18:41:00 GMT 2014 armv6l является частью MOTD. Однако нет необходимости в конвейере, s sh будет запускать последний аргумент через пользовательскую оболочку, без необходимости передавать его в STDIN. Это может быть ограничено значением MAX_ARG_STRLEN (что составляет ~ 128 КБ), но если у вас есть скрипт такого размера, вам, вероятно, следует сначала отправить его на хост.

$ ssh pi '
for w in $(echo "/var/asd/dsa/123" | tr "/" " ")
do
   echo $w >&2
   echo "123"
done 2>&1 | tee
'
var
123
asd
123
dsa
123
123
123

Примечание: Это может быть ограничено MAX_ARG_STRLEN (что составляет ~ 128 КБ), но если у вас есть скрипт такого размера, вы, вероятно, должны сначала найти его на хосте.

Примечание: pi - это тестовый сервер, который я использую, замените его соответствующей информацией о подключении.

0 голосов
/ 05 марта 2020

Проблема в том, что локальная оболочка интерполирует ваши выражения $ перед отправкой их в сеанс s sh. Вы можете предотвратить это, заключив в кавычки ваш heredo c тег: 'EOF'.

ssh -o "StrictHostKeyChecking no" -i $PEM_PATH $SERVER_USER@$SERVER_IP <<'EOF'
    for w in $(echo "/var/asd/dsa/123" | tr "/" " ") ; do echo $w >&2; echo "123"; done
EOF

С указанным выше кодом $(echo "/var/asd/dsa/123" | tr "/" " ") ; отправляется на сервер, а не заменяется локально.

...