¿Usar aquí-documento en una sola línea?

¿Usar aquí-documento en una sola línea?

Tengo un script simple que ejecuta comandos en un host remoto usando sshun 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 awkde 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 getHostsmatriz 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.awkgrepawkawk

Dentro del bucle, parece como si quisieras obtener información sobre un proceso rsynco iasyncproceso que pertenece a un researchusuario.

Esto se hace mejor con pgrep:

pgrep -l -U research 'rsync|iasync'

Para señalar estos procesos, utilice pkillen lugar de pgrepy suelte la -lopció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 xargslo admite, se podría hacer que ejecute varios sh -cprocesos a la vez con -P n, donde nestá el número de sh -ccomandos simultáneos que xargsdeben 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 "researchpatrón "), se deben escapar con un \, al igual que los $caracteres.

información relacionada