Bash

包含引號的變數的語法錯誤

  • May 18, 2016

我在 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不帶引號編寫時,這會拆分PGWAat 空格¹的值。引號字元在那裡沒有特殊含義,因此您以單詞-o, ProxyCommand="ssh, gateway1, nc, %hand結尾%p"

請參閱為什麼我的 shell 腳本會因空格或其他特殊字元而窒息?更多解釋。

雙引號之外的變數擴展幾乎總是一個錯誤。除非您知道為什麼需要去掉雙引號,否則這總是一個錯誤。

您需要做的是將兩個參數傳遞給 SSH 命令:-oProxyCommand=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 …

¹加上其他無關緊要的事情。

引用自:https://unix.stackexchange.com/questions/281897