リモートマシンでローカルスクリプトを実行し、引数を含めるにはどうすればよいですか?


116

ローカルで実行すると正常に実行されるスクリプトを作成しました。

./sysMole -time Aug 18 18

引数"-time""Aug""18"、および"18"は、スクリプトに正常に渡されます。

現在、このスクリプトは、リモートマシンで実行されるように設計されていますが、ローカルマシンのローカルディレクトリから実行されます。例:

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

それもうまくいきます。しかし、たとえば、前述の引数(-time Aug 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

私が間違っていることを教えてください、これは非常にイライラします。


1
「bash -s」は、標準入力(ファイルなど)からスクリプトを実行する方法の1つです。
アレン

回答:


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>

4
あなたは天才です!あなたのレベルに到達するには何をしなければなりませんか?私はたくさんの仕事をカットしました。本当にありがとう。
アレン

14
@AllenD-質問を続けるだけで、できるだけサイトに参加してみてください。私は毎日何か新しいことを学ぼうとしています。あなたの質問の前に、私もこれを行う方法を知りませんでした。8-)。ご質問ありがとうございます!
slm

5
リダイレクトは、コマンド内の任意の時点で表示されますのでご注意:例えばbash -s -- --time bye < ./ex.bash、あるいは< ./ex.bash bash -s -- --time bye。これは、シェルが最初にリダイレクト命令を取り出し(コマンド内の場所に関係なく)、次にリダイレクトをセットアップしてから、リダイレクトを適切に実行して残りのコマンドラインを実行するためです。
レスマナ

@sim私はこれとまったく同じことをしようとしていますが、コマンドラインからではなく、スクリプト内から行います。これを行う方法のアイデアはありますか?何らかの理由で、正確な答えをバッククォートで囲むことはまったく機能しません。代わりにローカルで指定されたスクリプトを実行し、出力はコマンドとしてssh
経由で

@ krb686 -私は新しいQ.としてそれを尋ねるだろう
SLM

5

任意の引数の処理について

実際に単一の文字列のみを使用している場合、つまり -time Aug 18 18、それからあなたは単にそれをハードコーディングすることができます、そして、既存の答えはあなたにそれを適切にする方法を教えます。一方、不明な引数を渡す必要がある場合(他のシステムに表示されるメッセージや、エンドユーザーが名前を制御できる場所で作成されたファイルの名前など)、さらに注意が必要です。


bashkshなど/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

十分に悪意のある引数データ(printf %qエスケープされる文字列に非印刷文字が存在する場合にbashで使用される非POSIX準拠の引用を利用しようとする)に対して安全であるために、/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

aaはlsを含むローカルファイルであると言う

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

127.0.0.1をリモートIPに変更します

これら2つは、疑似tty割り当てに関するメッセージを提供しますが、機能します。

$ 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


2
これが質問にどれだけ答えているのかを見るのに苦労しています。
ChrisWue

品質とフォーマットは疑わしいです。受け入れられた回答にも存在しない新しい有用な情報も見当たりません。
ジュリーペレティエ

@JuliePelletier私は受け入れられた答えにないいくつかの「猫」の例を挙げました。物事を行う別の方法を知ることは良いことです。
-barlop

それは良いことではありません。あなたの猫は役に立たない。
スコット

2
あら。誰もが少なくとも今までにこのフレーズを聞いたことがあると思っていたので、私は猫の無駄な使用へのリンクを省きました。どうやらそれは私の側の悪い仮定でした。
スコット
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.