一重引用符または二重引用符内で変数を拡張する方法

一重引用符または二重引用符内で変数を拡張する方法

2つのシステムがあり、同じディレクトリ構造を持っています。ローカルシステムで複数のコマンドを実行し、リモートシステムでも同じコマンドを実行したいと思います。

ワイルドカードを使用するので、パッケージの新しいバージョンがあるときにbashスクリプトを再編集する必要はありません!

私のbashスクリプトには次の行があります。

varWheelsDir="/tmp/wheels"
set -x
# Install local
pip3 install --force-reinstall --user "${varWheelsDir}/bbw"*
# Install remote
ssh -t admin@otherhost "pip3 install --user '${varWheelsDir}/bbw$*'"

これも拡張されました

+ pip3 install --user /tmp/wheels/bbw-2.10.0-py3-none-any.whl
+ ssh -t admin@otherhost 'pip3 install --user '\''/tmp/wheels/bbw'\'''

明らかに、SSHラインの拡張は機能しません。

どのように入力するのか知っていますssh -t

答え1

明らかに、SSHラインの拡張は機能しません。

この文の文法的問題を取り除いて、拡張が期待どおりに機能しないことを除いて、拡張が「機能しない」ことは明らかではありません。拡張方法と期待する内容を含めると役に立ちます。

SSHクライアントではなく、リモートホストで拡張が行われることを意味しているようです。この場合、ローカルシェルに渡された引数をエスケープしますが、リモート拡張を許可するには引用符も変更する必要があります。

ssh -t admin@otherhost "pip3 install --user \"\${varWheelsDir}/bbw\*\""

答え2

sshコマンドが「build」されたときにどの部分が拡張されるのか、結果は何であるのか、リモートホストでコマンドを実行すると、どの部分が拡張されるのかを確認する必要があります。

最初の試み

ssh -t admin@otherhost "pip3 install --user '${varWheelsDir}/bbw$*'"
# expands to
ssh -t admin@otherhost "pip3 install --user '/tmp/wheels/bbw'"
# and executes on the other host
pip3 install --user '/tmp/wheels/bbw'

$*ここでは使用できない位置パラメータに拡張されます。バラよりhttps://www.gnu.org/software/bash/manual/html_node/Special-Parameters.html#index-_002a

そうすれば

ssh -t admin@otherhost "pip3 install --user '${varWheelsDir}/bbw'*"
# it should expand to
ssh -t admin@otherhost "pip3 install --user '/tmp/wheels/bbw'*"
# which executes on the other host
pip3 install --user '/tmp/wheels/bbw'*

*ローカルホストでのグロービングを防ぐために二重引用符の内側にありますが、リモートホストでファイルのグロービングを許可するには一重引用符の外にあります。)

疲れています。

x=/tmp
ssh -t otherhost "ls -l '$x/'*"

私のために働いて、リモートホストの一時ディレクトリをすべてリストしました。

答え3

多くのシステムには、次のことができる設定がAcceptEnv LC_*あります。sshd

export LC_DIR="$varWheelsDir"
shell_code='
  pip3 install --force-reinstall --user "$LC_DIR"/bbw*
'
eval "$shell_code" # interpreted by current shell

ssh -e SendEnv=LC_DIR -t admin@otherhost "$shell_code"
  # interpreted by the login shell of admin on otherhost,
  # assuming it is Bourne-like

同じシェルコードを使用してローカルおよびリモートで実行し、$LC_DIR同じ内容で変数を共有します。

または、ローカルシェルがzshで、オンのログインシェルがBourneに似ていることがわかっている場合は、admin安全な方法でotherhostローカル変数の内容を含めて参照するシェルコードを設定できます。$varWheelsDir

pip3 install --force-reinstall --user "${varWheelsDir}"/bbw* # local
ssh -t admin@otherhost "
  pip3 install --force-reinstall --user ${(qq)varWheelsDir}/bbw"* # remote

${(qq)var}ここでは、単一引用符を使用してsh構文の内容を引用します($var任意のデータを参照する最も安全な形式)。

最新バージョンには拡張引用符演算子がbashありますが、場合によっては移植できない bash 関連の構文を生成し、単一引用符以上を使用するため、 on のログインシェルが発生した場合にのみ機能します (好ましくは同じバージョンで実行中)。同じロケール)。${var@Q}$varadminotherhostbash

adminログインシェルがotherhostBourneのシェルに似ていることを保証できない場合は、次を参照してください。リモートユーザーのログインシェルを知らず、SSHを介して任意の単純なコマンドをどのように実行できますか?可能な方法。

関連情報