쉘 스크립트의 현재 쉘에서 프로그램을 실행합니다.

쉘 스크립트의 현재 쉘에서 프로그램을 실행합니다.

.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

이것은 작동하지만 현재 셸의 소유권을 부여하는 데 문제가 있습니다. 연결 후 스크립트가 정지됩니다(ssh가 하위 쉘에서 시작된 것 같기 때문입니다). 예를 들어 종료를 입력하고 ssh 명령이 종료되면 출력을 볼 수 있습니다.

터미널에서 ssh 명령을 실행하는 것과 동일한 동작을 얻을 수 있도록 스크립트를 실행할 때 현재 셸에 자동으로 소유권을 부여하고 싶습니다.

&& zsh추가 또는 사용 eval과 같은 다양한 방법을 시도했지만 exec이들 중 어느 것도 작동하지 않았습니다. 어떻게 해야 하나요?

답변1

"$($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
)"

관련 정보