1

I made a little shell script, that parses the .ssh config and allows me to pick an entry with fzf, and then connects to that host:

#!/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

That works, but I am having problems giving ownership to the current shell. When connected, the script freezes (because ssh is started in a subshell I imagine). Once I type e.g. exit, and the ssh command terminates, I can see the output.

I want to automatically give ownership to the current shell when the script is run, so that I get the same behavior like running the ssh command from within my terminal.

I tried all sorts of things like appending && zsh or using eval or exec, but none of these worked. How can I do this?

2
  • Note that ssh **<TAB> with the default keybindings of fzf will already invoke fzf to select the host to connect to (github.com/junegunn/fzf#host-names).
    – Wieland
    Commented May 31, 2021 at 16:54
  • cat file | awk '...' is functionally identical to awk '...' file, except the shorter version is better code. cat file is usually unnecessary Commented May 31, 2021 at 20:12

1 Answer 1

1

Try changing "$($choice)" to simply $choice (no quotes) -- that should expand the awk output into words and spawn the ssh command from the current process


This looks like it might be a problem

if (ip || alias && alias != "*") {
    if (port == "") port = "22"
    print "ssh " username "@" ip " -i " id_file " -p " port
}

What happens if ip is empty but alias is not? You'll enter the block, but you don't use the alias variable anywhere. You might want

if (!ip) { ip = alias }
if (ip && ip != "*") { ...

This might work as an alternative way to structure the function. Untested:

remote_host_connect() {
    awk '...' $HOME/.ssh/config \
    | fzf \
    | sh </dev/tty >/dev/tty 2>&1
}

This works for me as a standalone script:

#!/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
)"
7
  • That doesn't do anything. I don't get any output. It just hangs while waiting for input. I know my input is being sent via ssh, because if I type exit, it prints "Connection to ... closed". But I dont get the interactive shell. Commented May 31, 2021 at 15:13
  • maybe you need ssh -t Commented May 31, 2021 at 15:17
  • Nope, same problem remains with the -t flag. I just saw your edit. Will try and report back. Commented May 31, 2021 at 15:38
  • I tried the suggestion from your last edit, but the problem still remains. When executing the script, I am prompted: zsh: suspended (tty output) /home/user/.scripts/script.sh Commented May 31, 2021 at 15:45
  • It would probably be better to make it a zsh function (that executes in your current, interactive zsh session) instead of a bash script that runs in a separate process. Commented May 31, 2021 at 15:47

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.