sudoを使用してsshにコマンドとローカル変数を渡すときに必要な引用とエスケープを避けるには?

sudoを使用してsshにコマンドとローカル変数を渡すときに必要な引用とエスケープを避けるには?

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 "$(と、デバッグ目的でリモート実行部分の出力を得ることができます。

"$()"ヒント:コメントに使用していても...ブロック内でペアのない一重引用符または二重引用符をエスケープする必要があるかもしれません。

関連情報