Here-Dokument in einem Einzeiler verwenden?

Here-Dokument in einem Einzeiler verwenden?

Ich habe ein einfaches Skript, das Befehle auf einem Remote-Host unter Verwendung ssheines Here-Dokuments ausführt.

Ich habe versucht, es mit einem Einzeiler in der Befehlszeile zu tun, konnte aber nicht herausfinden, wie ich das Here-Dokument außerhalb eines Skripts erstellen kann. Ist das möglich? Ich habe einige Zeit damit verbracht, zu googeln und Dokumentationen zu Here-Dokumenten zu lesen, aber es ist mir nicht eingefallen.

Dieses Skript funktioniert einwandfrei. Ich brauchte den Here-Document-Abschnitt, um es awkremote über SSH auszuführen, aber für einfache Dinge verwende ich normalerweise lieber Einzeiler:

#!/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

Wahrscheinlich übersehe ich etwas Einfaches … Trotzdem danke für alle Vorschläge :)

Antwort1

Ich sehe nicht wirklich die Notwendigkeit, etwas bezüglich der Verwendung eines Here-Dokuments zu unternehmen, aber ichTunsehen Sie, dass Sie andere Dinge in Ihrem Skript erheblich vereinfachen können (was wiederum das hier vorliegende Dokument überflüssig macht).

Zunächst getHostskann die Pipeline zum Auffüllen Ihres Arrays vereinfacht werden (es gibt selten einen Grund, grepin zu leiten awk) und das gesamte Array kann entfernt werden:

curl -s 'http://assetts.lab/all_hosts' |
awk -F ' ' '!/^#/ && $1 ~ /db/ { print $1 }' |
while IFS= read -r remote; do
   # rest of code
done

grepHier habe ich Ihren + awk+ grep-Befehl zu einem einzigen Befehl kombiniert awk. Außerdem habe ich den awkBefehl die Hostnamen direkt in die Schleife einspeisen lassen, anstatt sie in einer Zwischenvariable zu speichern.

rsyncInnerhalb der Schleife sieht es so aus, als ob Sie Informationen zu einem Objekt oder iasyncProzess eines Benutzers abrufen möchten research.

Am besten geht das mit pgrep:

pgrep -l -U research 'rsync|iasync'

Um diese Prozesse zu signalisieren, verwenden Sie pkillanstelle von pgrepund lassen Sie die -lOption weg.

Das vollständige Skript lautet dann:

#!/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

Oder verwenden Sie 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 {}

Falls Ihr Unternehmen dies unterstützt, können Sie damit mehrere Prozesse gleichzeitig xargsausführen , wobei die Anzahl der Befehle ist, die gleichzeitig ausgeführt werden sollen.sh -c-P nnsh -cxargs

Antwort2

Die EOF-Bash-Funktion dient grundsätzlich der Verwendung wie in Ihrem Beispiel, d. h. um mehrere Textzeilen an einen anderen Befehl zu senden.

Wenn Sie dies als Einzeiler möchten, muss das EOF weg.

Um einen Befehl auf einem Remote-Host mit SSH auszuführen, müssen Sie nur Folgendes tun:

ssh host command

Zum Beispiel:

ssh host "ls -alh"

führt den Befehl auf dem Host aus und gibt die Ausgabe auf der Konsole zurück.

Ihr Beispielcode könnte in einer einzigen Zeile umgeschrieben werden, wenn Sie auf die Verwendung der Anführungszeichen achten, etwa so:

ssh host "ps -ef | egrep 'rsync|iasync' | awk -F' ' '{if (\$1 ~ \"research\") print \$2}'"

Dieser String in doppelten Anführungszeichen setzt die Argumente einzelner Befehle in einfache Anführungszeichen. Wenn weitere Anführungszeichen erforderlich sind (das "research"-Muster), müssen diese \und die $Zeichen mit einem maskiert werden.

verwandte Informationen