![Ejecute múltiples comandos de forma remota usando el script bash](https://rvso.com/image/191769/Ejecute%20m%C3%BAltiples%20comandos%20de%20forma%20remota%20usando%20el%20script%20bash.png)
Tengo que iniciar sesión en servidores remotos a través de ssh e ir a la carpeta tmp y allí tengo que ejecutar el comando rm. Pero cuando ejecuto el siguiente script, va al servidor remoto pero no va a la carpeta temporal ni ejecuta el comando rm.
#!/bin/bash
for i in `cat list`
echo $server
echo "------------------------------------------"
ssh $server << MYCOMMANDS
cd /tmp
rm log52.log
MYCOMMANDS
Respuesta1
El único problema real con su código es que su bucle carece de do
and done
, lo que le daría errores de sintaxis, y que lo está utilizando i
como variable de bucle pero intenta conectarse con alguna server
variable que bien puede no estar configurada.
Aparte de eso, está utilizando cat
una sustitución de comando sin comillas que esgeneralmentees una mala idea si no está seguro de que leerá cadenas sin espacios en blanco ni caracteres globales en los nombres de archivos (aunque la mayoría de los nombres de host se comportan bien a este respecto).
La mayoría de las veces es mejor leer la entrada línea por línea así:
while IFS= read -r remote; do
ssh -n "$remote" 'rm -f /tmp/log52.log'
done <list
Estoy usando ssh -n
aquí para dejar ssh
de leer su flujo de entrada estándar (que estaría conectado al list
archivo). Sin -n
, ssh
leería el contenido restante de list
y su bucle solo ejecutaría una única iteración.
Alternativamente, si realmente desea leer los comandos de un documento aquí:
while IFS= read -r remote; do
ssh -T "$remote" <<'END'
rm -f /tmp/log52.log
END
done <list
Aquí, estoy usando ssh -T
para deshabilitar explícitamente la asignación de pseudoterminal, lo cual no es necesario ya que no estamos haciendo nada que requiera la interacción del usuario. Lo hago porque ssh
notaré que su flujo de entrada estándar tiene datos, por lo que nos advertirá sobre no tener una terminal funcional en el sistema remoto para hacer cosas interactivas. No necesitamos -n
aquí ssh
ya que estamos reasignando el flujo de entrada estándar ssh
desde el documento aquí.
Pero el bucle podría ser reemplazado por el comando único
xargs -I {} ssh {} 'rm -f /tmp/log52.log' <list
... donde xargs
leerá la utilidadlíneasdel archivo list
, reemplace {}
el ssh
comando con una línea leída del archivo y realice la acción de acceder a los sistemas remotos para eliminar el archivo específico. Lo estoy usando rm -f
para no causar un error si no hay ningún archivo para eliminar.
Algunas implementaciones xargs
permiten la ejecución paralela de la utilidad con, por ejemplo, -P 4
(mantendría como máximo cuatro ssh
comandos simultáneos a la vez).
Respuesta2
#! /bin/bash
for i in `cat list`
do
echo $i
echo "-------------------------"
ssh $i "rm /tmp/log52.log"
done
Si solo necesita eliminar un único archivo, es posible que desee simplemente especificarlo en una sola línea. Además, puede resultarle útil agregarlo -f
al archivo rm
.
Respuesta3
No puedes simplemente redirigir la entrada estándar de una sesión ssh de esa manera. Deberías ver un mensaje de error parecido a:
El pseudoterminal no se asignará porque la entrada estándar no es un terminal
Debe usar la opción -tt para ssh para forzar la asignación de un pseudotty. Prueba esto:
#!/bin/bash
for i in `cat list`
echo $server
echo "------------------------------------------"
ssh -tt $server << MYCOMMANDS
cd /tmp
rm log52.log
MYCOMMANDS