
Tengo un script simple que ejecuta comandos en un host remoto usando ssh
un documento aquí.
Estaba intentando hacerlo con una sola línea en la línea de comando, pero no pude entender cómo hacer el documento aquí fuera de un script. ¿Es posible? Pasé algún tiempo buscando en Google y leyendo documentación sobre documentos aquí, pero no me llegaba.
Este script funciona bien: necesitaba la sección de documento aquí para ejecutarlo awk
de forma remota a través de ssh, pero generalmente me gusta hacer frases ingeniosas para cosas simples:
#!/bin/bash
# it looks up all my hosts with 'db' in the name
# then gets the PID of any rsyncs running as user 'research'
# and pumps them into xargs
getHosts=(`curl --silent "http://assetts.lab/all_hosts" | grep -v ^# | awk -F" " '{print$1}'|grep db`)
for BOX in ${getHosts[@]};do
echo "$BOX: "
ssh -T sshUser@$BOX <<"EOF"
ps -ef | egrep "rsync|iasync" | awk -F" " '{if ($1 ~ "research") print $2}'|sudo xargs -i ps -fp '{}'
#ps -ef | egrep "rsync|iasync" | awk -F" " '{if ($1 ~ "research") print $2}'|sudo xargs -i kill '{}'
EOF
echo
done
Probablemente me estoy perdiendo algo simple... De todos modos, gracias por cualquier sugerencia :)
Respuesta1
Realmente no veo la necesidad de hacer nada con respecto al uso de un documento aquí, perohacerVea que puede simplificar bastante otras cosas en su script (lo que a su vez hace que el documento aquí quede obsoleto).
En primer lugar, la canalización para poblar su getHosts
matriz se puede simplificar (rara vez hay una razón para canalizarla grep
) awk
, y se puede eliminar toda la matriz:
curl -s 'http://assetts.lab/all_hosts' |
awk -F ' ' '!/^#/ && $1 ~ /db/ { print $1 }' |
while IFS= read -r remote; do
# rest of code
done
Aquí he combinado su comando grep
++ en un solo comando. También dejé que el comando introduzca los nombres de host directamente en el bucle en lugar de almacenarlos en una variable intermedia.awk
grep
awk
awk
Dentro del bucle, parece como si quisieras obtener información sobre un proceso rsync
o iasync
proceso que pertenece a un research
usuario.
Esto se hace mejor con pgrep
:
pgrep -l -U research 'rsync|iasync'
Para señalar estos procesos, utilice pkill
en lugar de pgrep
y suelte la -l
opción.
El guión completo se convierte en:
#!/bin/sh
curl -s 'http://assetts.lab/all_hosts' |
awk -F ' ' '!/^#/ && $1 ~ /db/ { print $1 }' |
while IFS= read -r remote; do
printf 'Processing host "%s"\n' "$remote"
ssh "$remote" 'pgrep -l -U research "rsync|iasync"'
done
O, usando xargs
:
#!/bin/sh
curl -s 'http://assetts.lab/all_hosts' |
awk -F ' ' '!/^#/ && $1 ~ /db/ { print $1 }' |
xargs -I {} sh -c '
printf "Processing host \"%s\"\n" "$1"
ssh "$1" "pgrep -l -U research \"rsync|iasync\""' sh {}
Si xargs
lo admite, se podría hacer que ejecute varios sh -c
procesos a la vez con -P n
, donde n
está el número de sh -c
comandos simultáneos que xargs
deben seguir ejecutándose.
Respuesta2
La función EOF bash se utiliza básicamente como lo hace en su ejemplo, es decir, para enviar varias líneas de texto a otro comando.
Si quieres que esto sea una sola línea, el EOF tiene que desaparecer.
Para ejecutar un comando en un host remoto usando ssh, todo lo que necesita hacer es:
ssh host command
Por ejemplo:
ssh host "ls -alh"
ejecutará el comando en el host y devolverá el resultado en la consola.
Su código de ejemplo podría reescribirse en una sola línea si toma nota de cómo usa las comillas, algo como esto:
ssh host "ps -ef | egrep 'rsync|iasync' | awk -F' ' '{if (\$1 ~ \"research\") print \$2}'"
Esta cadena entre comillas dobles coloca los argumentos de los comandos individuales entre comillas simples. Cuando se necesitan más comillas dobles (el "research
patrón "), se deben escapar con un \
, al igual que los $
caracteres.