.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
)"