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?
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:
los cambios clave son:
– el comando
declare -f
se utiliza dentro del documento here para copiar la definición de la funcióndomove()
en el shell remoto antes de llamarla.– la sintaxis
\$1
se utiliza dentro del documento here para pasar el argumento adomove()
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óndomove()
en el shell remoto antes de llamarla.– la sintaxis
\$1
se utiliza dentro del documento here para pasar el argumento adomove()
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.>