Ejecutar programa en el shell actual dentro del script de shell

Ejecutar programa en el shell actual dentro del script de shell

Hice un pequeño script de shell que analiza la configuración .ssh y me permite elegir una entrada con fzf y luego conectarme a ese 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

Eso funciona, pero tengo problemas para otorgar propiedad al shell actual. Cuando se conecta, el script se congela (porque ssh se inicia en un subshell, me imagino). Una vez que escribo, por ejemplo, salir y el comando ssh finaliza, puedo ver el resultado.

Quiero otorgar automáticamente propiedad al shell actual cuando se ejecuta el script, para obtener el mismo comportamiento que ejecutar el comando ssh desde mi terminal.

Intenté todo tipo de cosas, como agregar && zsho usar evalo exec, pero ninguna funcionó. ¿Cómo puedo hacer esto?

Respuesta1

Intente cambiar "$($choice)"a simplemente $choice(sin comillas): eso debería expandir la salida de awk en palabras y generar el comando ssh del proceso actual.


Esto parece que podría ser un problema.

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

¿Qué pasa si ipestá vacío pero aliasno lo está? Ingresarás al bloque, pero no usarás la variable alias en ninguna parte. Podrías querer

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

Esto podría funcionar como una forma alternativa de estructurar la función. No probado:

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

Esto me funciona como un script independiente:

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

información relacionada