Shell-Script
如何通過多個 SSH 在遠端機器上執行帶有空格的本地腳本?
類似於我的問題here,除了有多個ssh,並且類似於這個問題,但參數中有空格……
我想
test.sh
通過多個 ssh 在遠端伺服器上執行本地腳本。test.sh
接受一個通常包含多個單詞的參數。test.sh:
#!/bin/bash while getopts b: opt; do case $opt in b) bval="$OPTARG" ;; esac done echo $bval
call_test.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 執行的腳本?
編輯:
我相信這個答案可以解決我遇到的問題。
如果通過 2 個 ssh 命令傳遞它,則必須對字元串進行兩次引號轉義。做一個額外的
PHRASE=${PHRASE@Q}
任務。但是請注意,
${var@Q}
andprintf %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