包含引號的變數的語法錯誤
我在 2 個網關後面有一堆 Linux 機器。要連接到我做的一組
ssh -o ProxyCommand="ssh gateway1 nc %h %p" machines_behind_1 ssh -o ProxyCommand="ssh gateway2 nc --proxy %h %p --proxy-type socks4" machines_behind_2
為了簡化這個過程,我想我會創建一個環境變數來保存代理命令並簡單地使用它。所以我做了
export PGWA='-o ProxyCommand="ssh gateway1 nc %h %p"' export PGWB='-o ProxyCommand="ssh gateway2 nc --proxy %h %p --proxy-type socks4"'
然後,根據我要連接的機器,我會做
ssh $PGWA machine_behind_1 ssh $PGWB machine_behind_2
但我得到這個錯誤 -
/bin/bash: -c: line 0: unexpected EOF while looking for matching `"' /bin/bash: -c: line 1: syntax error: unexpected end of file
知道為什麼嗎?
我不能使用任何 ssh_config 技巧,因為我不提前知道主機名。我可能會在 gateway1 後面創建一個新的虛擬機,我需要使用第一個代理命令。
我唯一能想到的就是創建一個新的別名、一個函式或一個 shell 腳本,它們基本上可以
ssh -o foo $@
使用並使用它。但是,我需要記住也為 scp 創建一個別名/shell 腳本或函式,我也經常使用它。我寧願能夠自動完成。我有點希望我可以
ssh gw1-host
在配置文件中做一些類似的操作並ssh -o foo host
通過第一個網關將其轉換為,但是在 ssh_config 中不允許這種正則表達式操作。如果沒有單獨的 ssh / scp 別名/腳本/函式,我可以通過任何方式實現我想要的嗎?
編輯:當我將環境變數複製粘貼到此處的堆棧交換中時,我在引用時犯了一個錯誤。
當您
$PGWA
不帶引號編寫時,這會拆分PGWA
at 空格¹的值。引號字元在那裡沒有特殊含義,因此您以單詞-o
,ProxyCommand="ssh
,gateway1
,nc
,%h
and結尾%p"
。請參閱為什麼我的 shell 腳本會因空格或其他特殊字元而窒息?更多解釋。
雙引號之外的變數擴展幾乎總是一個錯誤。除非您知道為什麼需要去掉雙引號,否則這總是一個錯誤。
您需要做的是將兩個參數傳遞給 SSH 命令:
-o
和ProxyCommand=ssh gateway2 nc --proxy %h %p --proxy-type socks4
.在 zsh 中,您可以設置
PGWA
為一個數組:PGWA=(-o 'ProxyCommand=ssh gateway2 nc --proxy %h %p --proxy-type socks4') ssh $PGWA …
在 bash 和 ksh 等其他 shell 中,這需要更多的輸入,因為它們的設計錯誤是不帶引號的變數擴展會被拆分,並且因為它們對數組有明確的語法:
PGWA=(-o 'ProxyCommand=ssh gateway2 nc --proxy %h %p --proxy-type socks4') ssh "${PGWA[@]}" …
一種可以在任何類似 sh 的 shell 中工作並且不需要太多輸入的方法是定義函式。
pgwa () { typeset c="$1"; shift "$c" -o 'ProxyCommand=ssh gateway2 nc --proxy %h %p --proxy-type socks4' "$@" } pgwa ssh …
但我認為最好的解決方案是將所有這些定義放在
.ssh/config
它們所屬的地方。這樣您就不需要任何 shell 技巧,並且配置可以在其他程序(rsync、sshfs、GUI 文件傳輸程序等)中工作。如果在 gateway1 後面添加新 VM,請添加條目.ssh/config
或使用ssh -o HostName=new-vm something-behind-gateway1 …
¹加上其他無關緊要的事情。