全体的に:
質問と例はローカルでテストできます。
sh -c "echo 'how to print single quote here'"
詳細:
次の構成があります。
upload_server = ('192.168.1.1', 10051)
これで、サーバー構成を置き換えるにはシェルスクリプトが必要です。ローカルでは、sedを使用して次のことができます。
sed -E 's/( upload_server = ).*/\\1('\"'$a'\"', 10051)/g' config.py
ただし、構成を変更する必要があるシステムがたくさんあります。
正しい計画はssh
for..inで使用することです。
for i in `cat hosts`; do ssh $i "cmd"; done
ただし、設定を変更するにはもう1つ必要ですsudo
。次のようになります。
for i in `cat hosts`; do ssh $i "sudo -c \"cmd\""; done
今sedで:
upload_server=123.123.123.123
upload_server_port=1000
cmd="sed -E 's/( upload_server = ).*/\\1('\"\"'\"'${upload_server}'\"'\"\"', ${upload_server_port})/g' config.py"
ssh $i "sudo -c \"${cmd}\""
構成結果:
upload_server = (123.123.123.123, 1000)
次のようにする必要があります。
upload_server = ('123.123.123.123', 1000)
今、引用符の使い方について混乱しました。 :(
ベストアンサー1
この場合、標準入力にsedスクリプトを渡すと、引用の問題を完全にバイパスできます。 SSHはローカル標準入力をリモートプロセスにルーティングし、sudoはそれを開いたままにし、sedはstdinからスクリプトを読み取ることができます。以下を使用して、標準入力の内容を渡すことができます。ここのドキュメント。
for i in `cat hosts`; do
ssh "$i" 'sudo sed -f - …' <<'EOF'
s/( upload_server = ).*/\1("$a", 10051)/g
EOF
done
より一般的には、stdinにデータを渡す必要がない限り、引用を心配することなくSSHを介してstdinのシェルフラグメントを渡すことができます。
for i in `cat hosts`; do
ssh "$i" sudo sh <<'EOF'
sed 's/( upload_server = ).*/\1("$a", 10051)/g' …
EOF
done
"$a"
設定ファイルを挿入するか、"something"
変数の値がローカルシェルにあるかは、あなたの質問からは明確ではありません。ローカル変数を参照するには、hereドキュメントを補間と組み合わせて使用し、hereドキュメントからバックスラッシュで保護します。 sedと2番目のコードスニペットのリモートシェルによる解析のため、変数の値には文字や改行を含めないでください。a
something
$\`
\/'
ssh "$i" sudo sh <<EOF
sed 's/( upload_server = ).*/\\1("$a", 10051)/g' …
EOF