PS1をリモートシステムに接続しようとしています/etc/profile
。この文字列を70以上のサーバーに追加する必要があるので、ssh
このPS1文字列をすべてのサーバーに追加します。ただし、PS1を送信しようとすると動作が停止し、コマンドを終了する必要があります。
これは命令です
ssh -v admin@remserv "sed '/002/a \ PS1=" \[\e[31m\]\n------------------------------------------------------------------------------------------------------------------------------ \n\n[\u@\h \W]\\$ - \# \[\e[0m\] " /etc/profile' "
私がここで何を見逃しているのでしょうか?
提案どおりにコマンドを編集します。
> ssh -vt admin@remserv printf "%s\n" "sudo sed -i.bak '/002/a \
> PS1="
> '\[\e[31m\']'\'n------------------------------------------------------------------------------------------------------------------------------ '\'n'\'n'[\u@\h \W']'\\'$ - '\'# '\[\e[0m\'] " /etc/profile' "
答え1
ssh ... "sed '/002/a \ PS1=" \[\e[31m\]\n--...- \# \[\e[0m\] " /etc/profile' "
^ ^ ^ ^
引用符付き文字列には、引用符のない2つの二重引用符があり、これはシェル(ssh接続のローカル側)によって削除されます。また、内部一重引用符はsed
コマンドとファイル名をカバーするように見えるため、リモートシェルで引用符を処理すると、実際にはイメージのssh出力に表示されますsed
。/002/a \ ... /etc/profile
(まあ、少なくともそれは私が考えているものです。二重引用符の問題は、少なくともコーヒーが十分でなければ私の脳には良くありません。)
次のコマンドを実行してデバッグできる必要があります。
ssh somewhere printf '"%s\n"' "sed '/002/... /etc/profile' "
1行に1つずつ引数を印刷するので、文字列がprintf
実際に分割された位置を確認する方が簡単です(echoは空白で連結されるので、はfoo
、bar
と同じように見えますfoo bar
)。フォーマット文字列の二重引用符は、リモコンのバックスラッシュをそのまま残します。
答え2
いいですね。この問題を解決するには、「\」文字を使用してください。
正しいコマンド
for i in `cat serverslist`; do ssh -t admin@$i "sudo sed -i.bak '/002/a \ PS1="\" '\\'['\\'e[31m'\\']'\\n'------------------------------------------------------------------------------------------------------------------------------ '\\'n'\\'n['\\'u@'\\'h '\(''\\'W'\)']'\\''\\'$ - '\\'# '\\'['\\'e[0m'\\'] \"" ' /etc/profile " ;done ;