引用された SSH コマンド

引用された SSH コマンド

奇妙なエラーが発生しましたが、何も見つかりませんでした。次のコマンドを使用してユーザーの説明を変更したいと思います。

$ sudo usermod -c "New Comment" user

これはサーバーにログインしたときに機能しますが、20台以上のサーバーで自動化したいと思います。通常、リストを使用してサーバーを介してループを実行してコマンドを実行できますが、この場合はエラーが発生します。

$ for i in `cat servlist` ; do echo $i ; ssh $i sudo usermod -c "New Comment" user ; done 
serv1
Usage: usermod [options] LOGIN

Options:
lists usermod options

serv2
Usage: usermod [options] LOGIN

Options:
lists usermod options
.
.
.

このループを実行すると、コマンドを誤って使用したかのようにエラーが返されますが、単一のサーバーで正しく実行されます。

SSHのマニュアルページを見てタグを試しましたが、-t-t -tも機能しませんでした。

perl -p -i -e同様のループを使用してファイルを編集しました。

なぜループできないのか知っている人はいますか?

答え1

SSH はシェルからリモートコマンドを実行します。パラメータリストの代わりに文字列をリモートシェルに渡します。コマンドに渡されたパラメーターはsshスペースで区切られます。パラメータはsshsudoおよびであるusermodため-c、リモートシェルでコマンドを表示できます。New Commentuser

sudo usermod -c New Comment user

usermodCommentユーザー名と偽の追加パラメータで解決されますuser

コメントが文字列として処理されるように、リモートシェルに引用符を渡す必要があります。最も簡単な方法は、リモートコマンド全体を一重引用符で囲むことです。このコマンドに一重引用符を使用する必要がある場合は、使用してください'\''

ssh "$i" 'sudo usermod -c "Jack O'\''Brian" user'

呼び出しを繰り返してエラーを無視する代わりに、sshpssh、mussh、Clustershなどの複数のサーバーでコマンドを実行するように設計されたツールを使用してください。より多くのサーバーでSSHを介したコマンド実行の自動化

答え2

for i in `cat servlist`;do echo $i;ssh $i 'sudo usermod -c "New Comment" user';done

または

for i in `cat servlist`;do echo $i;ssh $i "sudo usermod -c \"New Comment\" user";done

答え3

次の便利なラッパースクリプトを使用できます。ssh.sh

2023/04/28に修正されました。最後に、@user202729が言及した問題を過度にプログラミングせずに解決する完璧なソリューションを見つけました。

最終的なSSHラッパーは次のとおりです。

#!/bin/bash
args=(); for v in "$@"; do args+=("$(printf %q "$v")"); done
ssh "${args[@]}"

コピーして貼り付けて実行して作成できます。

cat <<'EOF' > ssh.sh
#!/bin/bash
args=(); for v in "$@"; do args+=("$(printf %q "$v")"); done
ssh "${args[@]}"
EOF

chmod +x ssh.sh

これにより、脱出を心配することなくSSHを介して安全に呼び出すことができますssh.sh

./ssh.sh host sudo usermod -c "New Comment" user

フルテスト:

まず、/tmp/show_args.sh ユーティリティを生成してすべての引数を表示します。

cat <<'EOF' > /tmp/show_args.sh
#!/bin/bash
for arg in "$@"; do echo "ARG$((++i))=${arg@Q}"; done
EOF

chmod +x /tmp/show_args.sh

完全なテストのために:

./ssh.sh 127.0.0.1 -n /tmp/show_args.sh "a a" "'b b'" '"c c"' '*' '()' $'line1\nline2' $'\001    a' 'zz   '

出力は次のとおりです

ARG1='a a'
ARG2=''\''b b'\'''
ARG3='"c c"'
ARG4='*'
ARG5='()'
ARG6=$'line1\nline2'
ARG7=$'\001    a'
ARG8='zz   '

すべてのパラメータが入力と同じであることがわかります。ノート

''\''b b'\'''

文字通り

'b b'

関連情報