Shell
在 shell 腳本中的目前 shell 中執行程序
我製作了一個小 shell 腳本,它解析 .ssh 配置並允許我使用 fzf 選擇一個條目,然後連接到該主機:
#!/bin/bash set -o nounset -o errexit -o pipefail list_remote_hosts() { choice="$(cat $HOME/.ssh/config | awk -v RS= -v FS=\\n -v IGNORECASE=1 ' { ip = "" alias = "" id_file = "" username = "" port = "" for (j = 1; j <= NF; ++j) { split($j, tmp, " ") if (tmp[1] == "Host") { alias = tmp[2] } if (tmp[1] == "Hostname") { ip = tmp[2] } if (tmp[1] == "IdentityFile") { id_file = tmp[2] } if (tmp[1] == "User") { username = tmp[2] } if (tmp[1] == "Port") { port = tmp[2] } } if (ip || alias && alias != "*") { if (port == "") { port = "22" } print "ssh " username "@" ip " -i " id_file " -p " port } } ' | fzf)" "$($choice)" } list_remote_hosts
那行得通,但是我在授予目前 shell 所有權時遇到了問題。連接後,腳本會凍結(因為 ssh 是在我想像的子 shell 中啟動的)。一旦我輸入例如 exit,並且 ssh 命令終止,我就可以看到輸出。
我想在腳本執行時自動授予目前 shell 的所有權,以便獲得與在終端中執行 ssh 命令相同的行為。
我嘗試了各種方法,例如附加
&& zsh
或使用eval
orexec
,但這些都不起作用。我怎樣才能做到這一點?
嘗試更改
"$($choice)"
為簡單$choice
(不帶引號)-應該將 awk 輸出擴展為單詞並從目前程序生成 ssh 命令這看起來可能是個問題
if (ip || alias && alias != "*") { if (port == "") port = "22" print "ssh " username "@" ip " -i " id_file " -p " port }
如果
ip
為空但alias
不是,會發生什麼?您將進入該塊,但不要在任何地方使用別名變數。你可能想要if (!ip) { ip = alias } if (ip && ip != "*") { ...
這可以作為建構子的另一種方法。未經測試:
remote_host_connect() { awk '...' $HOME/.ssh/config \ | fzf \ | sh </dev/tty >/dev/tty 2>&1 }
這對我來說是一個獨立的腳本:
#!/bin/bash eval "$( awk -v RS= -F'[[:space:]]+' '{ for (i=1; i<NF; i+=2) data[$i]=$(i+1) ip = (data["HostName"] ? data["HostName"] : data["Host"]) if (ip && ip != "*") printf "ssh %s@%s %s %s\n", (data["User"] ? data["User"] : ENVIRON["LOGNAME"]), ip, (data["IdentityFile"] ? "-i " data["IdentityFile"] : ""), "-p " (data["Port"] ? data["Port"] : 22) }' ~/.ssh/config \ | fzf )"