es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Llamadas de función en documento aquí para un script de shell de Unix.

Estoy trabajando en un script de shell para mover algunos archivos. Este script necesita ser capaz de operar en archivos ya sea en una máquina local o en un servidor remoto dependiendo de los argumentos que se le pasen. He logrado crear una función simple que hace lo que quiero. Lo que no logro entender es cómo utilizar esa función en un Here document para que pueda ser ejecutado en el servidor remoto. Encontré una pregunta similar aquí: https://stackoverflow.com/questions/21953160/from-shell-script-can-we-invoke-function-from-here-document pero las respuestas proporcionadas no funcionan para mí.

Aquí está lo que he logrado hasta ahora:

myscript.sh

REMOTE_HOST=myserver
JETTY_BASE=/opt/web/jetty

doMove()
{
echo “$JETTY_BASE/webapps/eyerep-data/$1”
sudo touch $JETTY_BASE/webapps/eyerep-data/$1/myfile
ls $JETTY_BASE/webapps/eyerep-data/$1;
}

moveRemote()
{
echo “intentando mover con here doc”
ssh -t $REMOTE_HOST “/bin/bash <<EOF
$(doMove $1)
EOF”
}

moveFiles()
{
case “$1” in
# despliegue remoto
remote)
moveRemote $2
;;
# despliegue local
local)
doMove $2
;;
*)
echo “Uso: myscript.sh {local|remote}”
exit 1
;;
esac
}

Si ejecuto el código anterior con:

> ./myscript.sh remote dev

Obtengo una salida como esta:

intentando mover con here doc
/bin/bash: línea 1: /opt/web/jetty/webapps/eyerep-data/: Es un directorio
/bin/bash: línea 2: dev: comando no encontrado
/bin/bash: línea 3: eyerep-data-dev.xml: comando no encontrado
/bin/bash: línea 4: eyerep-data-local.xml: comando no encontrado
/bin/bash: línea 5: local: solo se puede utilizar en una función

Al revisar la salida, parece que está intentando pasar la salida de las llamadas de ‘echo’ y ‘ls’ a /bin/bash como comandos en lugar de imprimirlos en la consola. Aunque este es un ejemplo artificial, me gustaría poder tener declaraciones de registro dentro de mi función que se impriman en la salida estándar. ¿Cuál es la mejor manera de manejar esto?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Una forma de abordar este problema es definir la función por separado fuera del documento Here, y luego llamarla dentro del documento Here usando el mismo argumento pasado a la función principal.

    Aquí hay una versión actualizada del script:

    #!/bin/bash
    
    REMOTE_HOST=myserver
    JETTY_BASE=/opt/web/jetty
    
    doMove()
    {
        echo "$JETTY_BASE/webapps/eyerep-data/$1"   
        sudo touch $JETTY_BASE/webapps/eyerep-data/$1/myfile
        ls $JETTY_BASE/webapps/eyerep-data/$1
    }
    
    # mover archivos de forma remota utilizando SSH
    moveRemote()
    {
        echo "intentando mover con el documento Here"
        ssh -t $REMOTE_HOST bash -s "$1" <<eof
        $(declare -f domove)
        domove \$1
    eof
    }
    
    # función principal para mover archivos
    movefiles()
    {   
        case "$1" in
            remote)
                moveremote $2
                ;;
            local)
                domove $2
                ;;
            *)
                echo "uso: myscript.sh {local|remote}"
                exit 1
                ;;
        esac        
    }
    
    # llamar a la función movefiles con los argumentos pasados
    movefiles "$@"
    

    los cambios clave son:
    – el comando declare -f se utiliza dentro del documento here para copiar la definición de la función domove() en el shell remoto antes de llamarla.
    – la sintaxis \$1 se utiliza dentro del documento here para pasar el argumento a domove() como un parámetro al shell remoto.
    – el comando bash -s se utiliza para invocar explícitamente el shell remoto.
    – se eliminan los mensajes de registro de la función domove() para evitar redirigirlos como comandos dentro del documento here.

    con estos cambios, el script debería funcionar como se espera e imprimir la salida en la consola, al tiempo que permite que la función domove() se ejecute en el servidor remoto dentro de un documento here. $(declare=”” -f=”” domove)=”” domove=”” \$1=”” eof=”” }=”” #=”” función=”” principal=”” para=”” mover=”” archivos=”” movefiles()=”” {=”” case=”” “$1″=”” in=”” remote)=”” moveremote=”” $2=”” ;;=”” local)=”” domove=”” $2=”” ;;=”” *)=”” echo=”” “uso:=”” myscript.sh=”” {local|remote}”=”” exit=”” 1=”” ;;=”” esac=”” }=”” #=”” llamar=”” a=”” la=”” función=”” movefiles=”” con=”” los=”” argumentos=”” pasados=”” movefiles=”” “$@”=”” “`=”” los=”” cambios=”” clave=”” son:=”” -=”” el=”” comando=”” declare="" -f=”” se=”” utiliza=”” dentro=”” del=”” documento=”” here=”” para=”” copiar=”” la=”” definición=”” de=”” la=”” función=”” domove()=”” en=”” el=”” shell=”” remoto=”” antes=”” de=”” llamarla.=”” -=”” la=”” sintaxis=”” \$1=”” se=”” utiliza=”” dentro=”” del=”” documento=”” here=”” para=”” pasar=”” el=”” argumento=”” a=”” domove()=”” como=”” un=”” parámetro=”” al=”” shell=”” remoto.=”” -=”” el=”” comando=”” bash="" -s=”” se=”” utiliza=”” para=”” invocar=”” explícitamente=”” el=”” shell=”” remoto.=”” -=”” se=”” eliminan=”” los=”” mensajes=”” de=”” registro=”” de=”” la=”” función=”” domove()=”” para=”” evitar=”” redirigirlos=”” como=”” comandos=”” dentro=”” del=”” documento=”” here.=”” con=”” estos=”” cambios,=”” el=”” script=”” debería=”” funcionar=”” como=”” se=”” espera=”” e=”” imprimir=”” la=”” salida=”” en=”” la=”” consola,=”” al=”” tiempo=”” que=”” permite=”” que=”” la=”” función=”” domove()=”” se=”” ejecute=”” en=”” el=”” servidor=”” remoto=”” dentro=”” de=”” un=”” documento=””></eof
    $(declare -f domove)
    domove \$1
    eof
    }

    función principal para mover archivos

    movefiles()
    {
    case “$1” in
    remote)
    moveremote $2
    ;;
    local)
    domove $2
    ;;
    *)
    echo “uso: myscript.sh {local|remote}”
    exit 1
    ;;
    esac
    }

    llamar a la función movefiles con los argumentos pasados

    movefiles “$@”
    “`

    los cambios clave son:
    – el comando declare -f se utiliza dentro del documento here para copiar la definición de la función domove() en el shell remoto antes de llamarla.
    – la sintaxis \$1 se utiliza dentro del documento here para pasar el argumento a domove() como un parámetro al shell remoto.
    – el comando bash -s se utiliza para invocar explícitamente el shell remoto.
    – se eliminan los mensajes de registro de la función domove() para evitar redirigirlos como comandos dentro del documento here.

    con estos cambios, el script debería funcionar como se espera e imprimir la salida en la consola, al tiempo que permite que la función domove() se ejecute en el servidor remoto dentro de un documento here.>

Comments are closed.