如何透過多個 SSH 在遠端電腦上執行參數中帶有空格的本機腳本?

如何透過多個 SSH 在遠端電腦上執行參數中帶有空格的本機腳本?

和我的問題類似這裡,除了多個 ssh,並且類似於這個問題但參數中有空格......

我想test.sh透過多個 ssh 在遠端伺服器上運行本地腳本。test.sh接受一個經常有多個單字的論點。

測試.sh:

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

呼叫測試.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}and printf %q(如下所述)都將使用$'...'引號轉義格式,遠端 shell 可能不支援該格式

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"

另外,您可以將整個腳本及其參數放在一個變數中,而不是透過標準輸入提供腳本,這是低效的(當從標準輸入讀取腳本時,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

相關內容