web-dev-qa-db-ja.com

sshを介してリモートマシンでローカルbashスクリプトを実行するにはどうすればよいですか?

リモートマシンに何もインストールせずに、1つの中央マシンから複数のリモートマシンに構成をプッシュする方法を探しています。

目的は、cfengineのようなツールで見つかるようなことを、エージェントがセットアップされていないマシンのセットで行うことです。これは実際には、既存のリモートマシンのセットにcfagentを設定するための優れた手法となる場合があります。

51
tremoloqui

スクリプトを渡し、それをパイプしてシェルを実行することにより、一時的にスクリプトを実行させることができます。

例えば.

echo "ls -l; echo 'Hello World'" | ssh me@myserver /bin/bash

当然、"ls -l; echo 'Hello World'"部分は、ローカルマシン上のファイルに保存されているbashスクリプトに置き換えることができます。

例えば.

cat script.sh | ssh me@myserver /bin/bash

乾杯!

55
tremoloqui

それを行うにはいくつかの方法があります。

1:

ssh user@remote_server 'bash -s' < localfile

2:

cat localfile  | ssh user@remote_server

3:

ssh user@remote_server "$(< localfile)"

3番は私の好みの方法です、それはインタラクティブなコマンドを許可します。 su -S service nginx restart

su -Sを使用すると、#1は残りのスクリプトをパスワードの質問の入力として使用します。)

21
Paul Verschoor

この目的のためにpythonのファブリックをお勧めします。

#!/usr/bin/python
# ~/fabfile.py

from fabric_api import *

env.hosts = ['Host1', 'Host2']
def deploy_script():
    put('your_script.sh', 'your_script.sh', mode=0755)
    Sudo('./your_script.sh')

# from Shell
$ fab deploy_script

開始するには、上記を使用できるはずです。あとは、Fabricの優れた ドキュメント を参照してください。補足として、Fabric内で完全にスクリプトを作成することは完全に可能です。コピーは不要ですが、すべてのマシンでスクリプトを変更するには、ローカルコピーを編集して再デプロイするだけでよいことに注意してください。さらに、APIの基本的な使用法を少し上回るだけで、スクリプトが現在実行されているホストや他の変数に基づいてスクリプトを変更できます。これは一種のPythonic Expectです。

13
Sam Halicke

これは、Ansibleがまさに使用されているものです。エージェントはなく、次のテキストファイルを作成するだけです。

/etc/ansible/hosts

次のような内容です。

[webhosts]
web[1-8]

これは、マシン「web1、web2 ... web8」がグループ「webhosts」にあることを指定します。その後、次のようなことができます:

ansible webhosts -m service -a "name=Apache2 state=restarted" --Sudo

sudoを使用して、すべてのマシンでApache2サービスを再起動します。

次のようなオンザフライコマンドを実行できます。

ansible webhosts -m Shell -a "df -h"

または、リモートマシンでローカルスクリプトを実行できます。

ansible webhosts -m script -a "./script.sh"

または、サーバーに適合させてデプロイするための完全な構成を備えたプレイブックを作成(詳細についてはドキュメントを参照)できます。

ansible-playbook webplaybook.yml

基本的には、複数のサーバーでコマンドを実行するためのコマンドラインツールとして使用し始め、必要に応じてその使用を完全な構成ツールに拡張できます。

5
seumasmac

this answer で説明されているように、 heredoc を使用できます。

ssh user@Host <<'ENDSSH'
#commands to run on remote Host
ENDSSH

ヒアドキュメントはテキストを送信するだけなので、ヒアドキュメントには注意する必要がありますが、実際には応答を待ちません。つまり、コマンドが実行されるのを待ちません。

3
BЈовић

ここでの答え( https://stackoverflow.com/a/2732991/475288 )は、plinkまたはsshを使用してリモートLinuxマシンでスクリプトを実行する場合に最適です。スクリプトがlinuxに複数行ある場合に機能します。

**ただし、ローカルlinux/windowsマシンにあるバッチスクリプトを実行しようとしていて、リモートマシンがWindowsであり、**を使用する複数の行で構成されている場合

plink root@MachineB -m local_script.bat

うまくいきません。

スクリプトの最初の行のみが実行されます。これはおそらくplinkの制限です。

解決策1:

複数行のバッチスクリプトを実行するには(特に、数行で構成される比較的単純な場合):

元のバッチスクリプトが次のとおりである場合

cd C:\Users\ipython_user\Desktop 
python filename.py

次のようにlocal_script.batファイルで次のように「&&」セパレータを使用して行を組み合わせることができます https://stackoverflow.com/a/8055390/475288

cd C:\Users\ipython_user\Desktop && python filename.py

この変更後、@ JasonR.Coombsによってここで指摘されているようにスクリプトを実行できます。 https://stackoverflow.com/a/2732991/475288

解決策2:

バッチスクリプトが比較的複雑な場合は、ここで@Martin (https://stackoverflow.com/a/32196999/475288

rem Open tunnel in the background
start plink.exe -ssh [username]@[hostname] -L 3307:127.0.0.1:3306 -i "[SSH
key]" -N

rem Wait a second to let Plink establish the tunnel 
timeout /t 1

rem Run the task using the tunnel
"C:\Program Files\R\R-3.2.1\bin\x64\R.exe" CMD BATCH qidash.R

rem Kill the tunnel
taskkill /im plink.exe
1
alpha_989

スクリプト内の各コマンドがすでにisプレフィックスがsshで、ホスト名/ ipまたはそのリストが引数としてスクリプトに渡されるようにスクリプトを書き直します(パスワードなし/ ssh-agentキーがある場合)認証の設定)。リモートコマンドからエラー/リターンコードを正しく渡すには、いくつかの作業が必要になる場合があります。

0
rackandboneman

単にスクリプトを最初にコピーしてから、それを実行しないのはなぜですか?

scp your_script.sh the_server:
ssh the_server "chmod +x your_script.sh; ./your_script.sh"

もちろん、それを誰でも書き込み可能な場所にアップロードしないように注意する必要があります。そのため、実行する前に(おそらくrootとして)他のユーザーがいじることはできません。

0
Dave Vogt

スクリプトが大きすぎず、bashまたはkshを使用している場合...

ssh vm24 -t bash -c "$(printf "%q" "$(< Shell-test.sh )")"

Stdinとstdoutはどちらも正しく動作しますが、スクリプトは引数のサイズ(通常は約100k)に制限されています。スクリプトの引数は、行末で機能する場合があります。追加の「-」引数の後に続く可能性があります。 ptyを割り当てる「-t」はオプションです。

注意:これはbashの補完を混乱させます。タブを打たないでください。

0
user3710044