Shell

在 shell 腳本中的目前 shell 中執行程序

  • May 31, 2021

我製作了一個小 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或使用evalor exec,但這些都不起作用。我怎樣才能做到這一點?

嘗試更改"$($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
)"

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