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

116

Я написал скрипт, который отлично работает при локальном исполнении:

./sysMole -time Aug 18 18

Аргументы «-time» , «Aug» , «18» и «18» успешно передаются в сценарий.

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

ssh root@remoteServer "bash -s" < /var/www/html/ops1/sysMole

Это также отлично работает. Но проблема возникает, когда я пытаюсь включить эти вышеупомянутые аргументы (время 18 августа 18) , например:

ssh root@remoteServer "bash -s" < /var/www/html/ops1/sysMole -time Aug 18 18

После запуска этого скрипта я получаю следующую ошибку:

bash: cannot set terminal process group (-1): Invalid argument
bash: no job control in this shell

Пожалуйста, скажите мне, что я делаю неправильно, это сильно расстраивает.

AllenD
источник
1
«Bash -s» - это один из способов выполнения сценария из стандартного ввода (т. Е. Файла).
AllenD

Ответы:

160

Вы были довольно близки с вашим примером. Он прекрасно работает, когда вы используете его с такими аргументами.

Пример скрипта:

$ more ex.bash 
#!/bin/bash

echo $1 $2

Пример, который работает:

$ ssh serverA "bash -s" < ./ex.bash "hi" "bye"
hi bye

Но это не подходит для следующих типов аргументов:

$ ssh serverA "bash -s" < ./ex.bash "--time" "bye"
bash: --: invalid option
...

В чем дело?

Проблема, с которой вы сталкиваетесь, заключается в том, что аргумент, -timeили --timeв моем примере, интерпретируется как переход к bash -s. Вы можете успокоиться bash, прекратив его, взяв любой из оставшихся аргументов командной строки для себя, используя --аргумент.

Нравится:

$ ssh root@remoteServer "bash -s" -- < /var/www/html/ops1/sysMole -time Aug 18 18

Примеры

# 1:

$ ssh serverA "bash -s" -- < ./ex.bash "-time" "bye"
-time bye

# 2:

$ ssh serverA "bash -s" -- < ./ex.bash "--time" "bye"
--time bye

# 3:

$ ssh serverA "bash -s" -- < ./ex.bash --time "bye"
--time bye

# 4:

$ ssh  < ./ex.bash serverA "bash -s -- --time bye"
--time bye

ПРИМЕЧАНИЕ: просто чтобы прояснить, что везде, где перенаправление появляется в командной строке, не имеет значения, потому что sshв любом случае вызывает удаленную оболочку с конкатенацией ее аргументов, цитирование не имеет большого значения, за исключением случаев, когда вам нужно заключить цитату в удаленную оболочку как в примере № 4:

$ ssh  < ./ex.bash serverA "bash -s -- '<--time bye>' '<end>'"
<--time bye> <end>
SLM
источник
4
ты гений! Что мне нужно сделать, чтобы попасть на ваш уровень? У меня много работы вырезано. Спасибо.
AllenD
14
@AllenD - просто продолжайте задавать вопросы и старайтесь участвовать на сайте как можно больше. Я всегда стараюсь узнавать что-то новое каждый день. До твоего вопроса я тоже не знала, как это сделать. 8-). Спасибо за ваш вопрос!
СЛМ
5
обратите внимание, что перенаправление может появиться в любой точке команды: например, bash -s -- --time bye < ./ex.bashили даже < ./ex.bash bash -s -- --time bye. это связано с тем, что оболочка сначала выполняет инструкцию по перенаправлению (независимо от того, где она находится в команде), затем устанавливает перенаправление, а затем выполняет оставшуюся часть командной строки с перенаправлением на месте.
Lesmana
@sim Я пытаюсь сделать то же самое, но из скрипта, а не из командной строки. Есть идеи, как это сделать? По какой-то причине заключение вашего точного ответа в кавычки не работает вообще. Вместо этого он запускает сценарий, указанный локально, и вывод отправляется в виде команды в bash через ssh
krb686
@ krb686 - я бы спросил его как новый вопрос.
slm
5

Об обработке произвольных аргументов

Если вы действительно используете только одну строку, т.е. -time Aug 18 18затем вы можете просто жестко закодировать его, и существующие ответы подскажут вам, как это сделать адекватно. С другой стороны, если вам нужно передать неизвестные аргументы (например, сообщение, которое будет отображаться в другой системе, или имя файла, созданного, где конечные пользователи могут контролировать его имя), тогда потребуется больше внимания.


С bashили kshкак/bin/sh

Если ваш пульт /bin/shпредоставлен bash или ksh, вы можете безопасно выполнить следующие действия со списком ненадежных аргументов, так что даже вредоносные имена (например $(rm -rf $HOME).txt) могут безопасно передаваться в качестве аргументов:

runRemote() {
  local args script

  script=$1; shift

  # generate eval-safe quoted version of current argument list
  printf -v args '%q ' "$@"

  # pass that through on the command line to bash -s
  # note that $args is parsed remotely by /bin/sh, not by bash!
  ssh user@remote-addr "bash -s -- $args" < "$script"
}

С любым POSIX-совместимым /bin/sh

Чтобы обезопасить себя от достаточно злонамеренных данных аргументов (пытаясь воспользоваться не-POSIX-совместимым цитированием, используемым printf %qв bash, когда в экранируемой строке присутствуют непечатаемые символы), даже с /bin/shбазовым-POSIX (таким как dashили ash) он становится немного интереснее:

runRemote() {
  local script=$1; shift
  local args
  printf -v args '%q ' "$@"
  ssh user@remote-addr "bash -s" <<EOF

  # pass quoted arguments through for parsing by remote bash
  set -- $args

  # substitute literal script text into heredoc
  $(< "$script")

EOF
}

Использование (для любого из вышеперечисленных)

Функции, приведенные выше, могут затем вызываться как:

# if your time should be three arguments
runRemote /var/www/html/ops1/sysMole -time Aug 18 18

...или же...

# if your time should be one string
runRemote /var/www/html/ops1/sysMole -time "Aug 18 18"
Чарльз Даффи
источник
-3

скажем, аа это локальный файл, который содержит ls

$ssh servername "cat | bash" < a.a

измените 127.0.0.1 на любой ваш удаленный IP

эти два сообщения сообщают о псевдотермическом распределении, но они работают.

$ cat a.a | ssh 127.0.0.1

$ ssh 127.0.0.1 <a.a

Или же

$ cat a.a | ssh 127.0.0.1 bash or

$ ssh 127.0.0.1 bash < a.a

barlop
источник
2
Я изо всех сил пытаюсь увидеть, насколько это отвечает на вопрос.
ChrisWue
Качество и форматирование сомнительно. Я не вижу никакой новой полезной информации, которой нет в принятом ответе.
Джули Пеллетье
@JuliePelletier Я привел несколько примеров «кошек», которых нет в принятом ответе. Хорошо знать альтернативные способы ведения дел.
Бароп
Это не очень хорошая вещь; ваши кошки бесполезны.
Скотт
2
О, Боже мой. Я пропустил ссылку на « Бесполезное использование кошки», потому что предположил, что все по крайней мере уже слышали эту фразу; по-видимому, это было плохое предположение с моей стороны.
Скотт