.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가 제가 생각하는 하위 쉘에서 시작되기 때문입니다). 예를 들어 exit를 입력하고 ssh 명령이 종료되면 출력을 볼 수 있습니다.
스크립트가 실행될 때 현재 셸에 자동으로 소유권을 부여하여 터미널 내에서 ssh 명령을 실행하는 것과 동일한 동작을 얻고 싶습니다.
or 을 추가 && 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
)"