複数のSSHを介してリモートコンピュータのパラメータにスペースを含むローカルスクリプトを実行するにはどうすればよいですか?

複数のSSHを介してリモートコンピュータのパラメータにスペースを含むローカルスクリプトを実行するにはどうすればよいですか?

私の問題に似ています。ここ、複数のSSHを除いて、次のようになります。この問題しかし、パラメータにスペースがあります...

test.sh複数のSSHを介してリモートサーバーでローカルスクリプトを実行したいと思います。test.sh多くの場合、2つ以上の単語で構成される主張を受け入れます。

テスト.sh:

#!/bin/bash
while getopts b: opt;
do
  case $opt in
    b)
       bval="$OPTARG"
       ;;
  esac
done
echo $bval

calltest.sh

#!/bin/bash
# Do some stuff
PHRASE="multi word arg"
ssh -A user@host1 "bash -s" -- < ./test.sh -b "${PHRASE@Q}"

実行すると./call_test.sh正しく出力されます。

multi word arg

call_test.shしかし、最後の行を次のように変更すると:

ssh -A user@host1 ssh -A user@host2 "bash -s" -- < ./test.sh -b "${PHRASE@Q}"

実行すると./call_test.sh以下が出力されます。

multi

デフォルトでは、単一のSSHから複数のSSHに変更すると、複数の単語の主張が壊れています。

複数のsshコマンドがすべての段階で複数の単語引数を引用解除していると思いますが、これを防ぐ方法がわかりません。複数のSSHで実行されるスクリプトに複数の単語引数を正常に渡す方法についてのアイデアはありますか?

編集する:

私は信じるこの回答発生した問題を解決しました。

ベストアンサー1

2つのsshコマンドを介して渡す場合は、文字列を二重引用符でエスケープする必要があります。追加の宿題でPHRASE=${PHRASE@Q}これを行います。

ただし、${var@Q}および(以下の説明)は両方とも引用符で処理された形式をprintf %q使用し、これはリモートシェルでサポートされていない可能性があります。$'...'

test.shスクリプトの最後の行をecho "$bval"次のように変更しますecho $bval

PHRASE="multi word     arg"
PHRASE=${PHRASE@Q}
ssh -A user@host1 ssh -A user@host2 "bash -s" -- < ./test.sh -b "${PHRASE@Q}"

multi word     arg

${var@P}以下を使用する代わりに、以前のバージョンのbashでサポートされていない拡張形式を使用できます。printf -v var %q:

PHRASE="multi word     arg"
printf -v PHRASE %q "$PHRASE"
printf -v PHRASE %q "$PHRASE"
ssh -A user@host1 ssh -A user@host2 "bash -s" -- < ./test.sh -b "$PHRASE"

あるいは、stdinを介してスクリプトを供給する代わりに、スクリプト全体とその引数を変数に入れることもできます。これは非効率的です(stdinからスクリプトを読み取ると、bashはすべてのバイト転送に対して読み取りシステムを実行します)。

printf -v cmd 'bash -c %q bash -b %q' "$(cat test.sh)" 'multi word   wahterve'
printf -v cmd %q "$cmd"
ssh localhost ssh localhost "$cmd"

multi word   wahterve

おすすめ記事