sudoを使用してsshにコマンドとローカル変数を渡すときに必要な引用とエスケープを避けるには?
この記事を使用して、引用を避けるための創造的な方法を提供した人を見つけました。これは良い考えのように聞こえますが、bashでは機能しません。私が見つけた提案は次のとおりです。ssh $host $FOO および ssh $host "sudo su user -c $FOO" タイプ構成で参照されます。
答え1
これは基本的なbashスクリプトの例です。
# Assign values to variables locally.
myvar1="myvalue1"
myvar2="myvalue2"
# Add your local commands here.
ssh myremotehost "$(
cat <<HEREDOC_EXPORT_VARIABLES
export myvar1="$myvar1"
export myvar2="$myvar2"
HEREDOC_EXPORT_VARIABLES
cat <<'HEREDOC_SUDO'
sudo -Eu root /bin/bash <<'HEREDOC_COMMANDS'
# Optionally display your variables.
echo "myvar1: $myvar1"
echo "myvar2: $myvar2"
# Add your remote commands here.
HEREDOC_COMMANDS
HEREDOC_SUDO
)" | tee logfile.log
さまざまな部分の説明。
変数はローカルに割り当てられます(リモートシステムでコマンドを実行する前)。
myvar1="myvalue1"
myvar2="myvalue2"
"$(
...)"
複数のコマンドをまとめてグループ化し、このブロック内で二重引用符を使用できます。
このドキュメントブロックをエクスポートすると(単一引用符を使用せずに)、ブロック内でローカル変数を使用できます。
cat <<HEREDOC_EXPORT_VARIABLES
...
...
HEREDOC_EXPORT_VARIABLES
リモートコマンドで使用するローカル変数をエクスポートします。
export myvar1="$myvar1"
export myvar2="$myvar2"
一重引用符で囲まれた外部doc-hereブロックはsudoコマンドをエコーするために使用され、リモート変数をエスケープするために内部doc-hereを必要としません(echo
改行なしで置き換えることができます)。
cat <<'HEREDOC_SUDO'
...
...
HEREDOC_SUDO
内部的には、ドキュメントブロックは、リモート変数をエスケープする必要がないように単一引用符で囲まれています。
sudo -Eu root /bin/bash <<'HEREDOC_COMMANDS'
...
...
HEREDOC_COMMANDS
-E
オプションをsudo
使用すると、以前にエクスポートした環境変数を保存できます。
tee logfile.log
出力が端末とログファイルに同時に反映されるようにします。
ボーナスでssh myremotehost "$(
line を次に置き換えるecho "$(
と、デバッグ目的でリモート実行部分の出力を得ることができます。
"$(
)"
ヒント:コメントに使用していても...ブロック内でペアのない一重引用符または二重引用符をエスケープする必要があるかもしれません。