
奇妙なエラーが発生しましたが、何も見つかりませんでした。次のコマンドを使用してユーザーの説明を変更したいと思います。
$ 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
スペースで区切られます。パラメータはssh
、sudo
およびであるusermod
ため-c
、リモートシェルでコマンドを表示できます。New Comment
user
sudo usermod -c New Comment user
usermod
Comment
ユーザー名と偽の追加パラメータで解決されますuser
。
コメントが文字列として処理されるように、リモートシェルに引用符を渡す必要があります。最も簡単な方法は、リモートコマンド全体を一重引用符で囲むことです。このコマンドに一重引用符を使用する必要がある場合は、使用してください'\''
。
ssh "$i" 'sudo usermod -c "Jack O'\''Brian" user'
呼び出しを繰り返してエラーを無視する代わりに、ssh
pssh、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'