[GNU] parallel+ssh で複数のリモートホストに複数のコマンドを実行させる

Pocket

仮想化大好きな皆さん( ノ゚Д゚)こんばんわ。…なんだこの顔文字。2ch辞書入れてる所為か、恐いな(;´Д`)
さて、家やAWSにサーバをお持ちの仮想化大好きの皆様は、もう100も 200もサーバを管理されていることと認知しています。したがって、マルチサイトを管理するための専用のツールなどを入れて、効率的に管理しているだろうと予想します。流石です。それにつけても、仮想化初心者の私の自宅サーバでは、マシンスペックも非力ですし、そんなにたくさんを管理することなど不可能です。ましてやお金がないのに、専用の管理ツールなんて…。

そのため、ごにょごにょして、ssh で rootでは non password で、DSAの鍵認証をさせて、あるサーバから、全てのサーバへログインできるようにして、複数のサイトへコマンドを実行できるように、なんてことをしています。例えばこんなワンライナーで。

1
$ for server in host01 host02 host03 ; do ssh $server "command01;command02" ; done

ただ、これではシングルタスクで順次実行ですし、”sudo” 使えないので、sudo したければ shell を組まねばなりません。

そこで登場したるは”GNU Parallel“コマンドです。複数ジョブを一気に実行できますし、コマンド化されているので sudoかけることもできます。先ほどの例を展開すると。

1
$ sudo parallel -j 3 ssh {} "command01;command02" ::: host01 host02 host03

簡単ですね。ホスト名の一覧の入ったファイルを指定して

1
$ cat hostlist | sudo parallel -j 3 ssh {} "command01;command02"

こんなことをすることもできます。便利ですねヽ(´ー`)ノ [I]なお、”-j 3″はジョブを3つ並行起動する。です。大きくすれば同時実行数が増えます。CPU使用率での表現も可能です。”-j … Continue reading

しかし、実行してみるとわかるのですが、command02parallel コマンド経由だと、ローカルホストで実行されてしまうんですね…。

parallel+sshで複数ホストに複数のコマンドを実行させる方法

対処は簡単でした。

1
$ cat hostlist | sudo parallel -j 3 ssh {} '"command01;command02"'

このように sshへの引数のダブルクォーテーションに、さらにシングルクォーテーションをつけるだけです。

これは、gnu parallel コマンドが sshへ引数を渡す時に、”command01;command02″ を展開して、command01;command02 として処理してしまうために、ssh へは ‘command01’ しか引き渡されないことに起因します。(多分)
shell として、parallel へは、”command01;command02″ を一つの引数として引き渡しているのですが、parallel が内部で展開してしまっているのだと思います。(多分)

まぁなんでもいいです。このようにやればうまく行くのです( ゚д゚ )クワッ!!

仮説の検証はどなたかにお任せしますので、動作の内情が分かったら教えてください。こっそりと。
あと、`command`もlocalで実行されてしまうので、次はこれをリモートで実行できないかとか変なことを考えてます。

References

References
I なお、”-j 3″はジョブを3つ並行起動する。です。大きくすれば同時実行数が増えます。CPU使用率での表現も可能です。”-j 300%”みたいに。多分

“[GNU] parallel+ssh で複数のリモートホストに複数のコマンドを実行させる” への3件の返信

  1. Consider using GNU Parallel’s –nonall:

    sudo parallel –nonall –slf hostlist -j 3 command01 ; command02

    You can make profile like this:

    echo “–nonall –slf hostlist -j 3” >.parallel/my_servers

    And then you can simply do:

    sudo parallel -J my_servers command01 ; command02

  2. Consider using GNU Parallel’s-nonall:

    sudo parallel --nonall --slf hostlist -j 3 command01 ; command02

    You can make profile like this:

    echo "--nonall --slf hostlist-j 3" > .parallel/my_servers

    And then you can use less quoting:

    sudo parallel -J my_servers 'command01 ; command02'

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください