GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wie speichert man einen Befehl in einer Variablen in einem Shell-Skript?

Verwenden Sie eval:

x="ls | wc"
eval "$x"
y=$(eval "$x")
echo "$y"

nicht Verwenden Sie eval ! Es besteht ein großes Risiko, dass willkürlicher Code ausgeführt wird.

BashFAQ-50 - Ich versuche, einen Befehl in eine Variable zu schreiben, aber die komplexen Fälle schlagen immer fehl.

Fügen Sie es in ein Array ein und erweitern Sie alle Wörter mit doppelten Anführungszeichen "${arr[@]}" zu nicht Lassen Sie die IFS teilen Sie die Wörter aufgrund von Word Splitting auf.

cmdArgs=()
cmdArgs=('date' '+%H:%M:%S')

und den Inhalt des Arrays darin sehen. Die declare -p ermöglicht es Ihnen, den Inhalt des Arrays darin mit jedem Befehlsparameter in separaten Indizes anzuzeigen. Wenn ein solches Argument Leerzeichen enthält, verhindert das Anführungszeichen beim Hinzufügen zum Array, dass es aufgrund von Word-Splitting geteilt wird.

declare -p cmdArgs
declare -a cmdArgs='([0]="date" [1]="+%H:%M:%S")'

und führen Sie die Befehle als

aus
"${cmdArgs[@]}"
23:15:18

(oder) insgesamt einen bash verwenden Funktion zum Ausführen des Befehls,

cmd() {
   date '+%H:%M:%S'
}

und rufen Sie die Funktion einfach auf

cmd

POSIX sh hat keine Arrays, so dass Sie am ehesten kommen können, wenn Sie eine Liste von Elementen in den Positionsparametern erstellen. Hier ist ein POSIX sh Möglichkeit, ein E-Mail-Programm auszuführen

# POSIX sh
# Usage: sendto subject address [address ...]
sendto() {
    subject=$1
    shift
    first=1
    for addr; do
        if [ "$first" = 1 ]; then set --; first=0; fi
        set -- "[email protected]" --recipient="$addr"
    done
    if [ "$first" = 1 ]; then
        echo "usage: sendto subject address [address ...]"
        return 1
    fi
    MailTool --subject="$subject" "[email protected]"
}

Beachten Sie, dass dieser Ansatz nur einfache Befehle ohne Umleitungen verarbeiten kann. Es kann keine Umleitungen, Pipelines, for/while-Schleifen, if-Anweisungen usw. verarbeiten

Ein weiterer häufiger Anwendungsfall ist die Ausführung von curl mit mehreren Header-Feldern und Payload. Sie können immer Argumente wie unten definieren und curl aufrufen auf dem erweiterten Array-Inhalt

curlArgs=('-H' "keyheader: value" '-H' "2ndkeyheader: 2ndvalue")
curl "${curlArgs[@]}"

Ein weiteres Beispiel,

payload='{}'
hostURL='http://google.com'
authToken='someToken'
authHeader='Authorization:Bearer "'"$authToken"'"'

Nun, da die Variablen definiert sind, verwenden Sie ein Array, um Ihre Befehlsargumente zu speichern

curlCMD=(-X POST "$hostURL" --data "$payload" -H "Content-Type:application/json" -H "$authHeader")

und führe jetzt eine ordnungsgemäße Erweiterung in Anführungszeichen durch

curl "${curlCMD[@]}"

var=$(echo "asdf")
echo $var
# => asdf

Bei dieser Methode wird der Befehl sofort ausgewertet und sein Rückgabewert gespeichert.

stored_date=$(date)
echo $stored_date
# => Thu Jan 15 10:57:16 EST 2015
# (wait a few seconds)
echo $stored_date
# => Thu Jan 15 10:57:16 EST 2015

Dasselbe gilt für Backtick

stored_date=`date`
echo $stored_date
# => Thu Jan 15 11:02:19 EST 2015
# (wait a few seconds)
echo $stored_date
# => Thu Jan 15 11:02:19 EST 2015

Verwendung von eval im $(...) wird später nicht ausgewertet

stored_date=$(eval "date")
echo $stored_date
# => Thu Jan 15 11:05:30 EST 2015
# (wait a few seconds)
echo $stored_date
# => Thu Jan 15 11:05:30 EST 2015

Mit eval wird ausgewertet, wenn eval verwendet wird

stored_date="date" # < storing the command itself
echo $(eval "$stored_date")
# => Thu Jan 15 11:07:05 EST 2015
# (wait a few seconds)
echo $(eval "$stored_date")
# => Thu Jan 15 11:07:16 EST 2015
#                     ^^ Time changed

Wenn Sie im obigen Beispiel einen Befehl mit Argumenten ausführen müssen, fügen Sie diese in die Zeichenfolge ein, die Sie speichern

stored_date="date -u"
# ...

Für Bash-Skripte ist dies selten relevant, aber eine letzte Anmerkung. Seien Sie vorsichtig mit eval . Werten Sie nur Zeichenfolgen aus, die Sie kontrollieren, niemals Zeichenfolgen, die von einem nicht vertrauenswürdigen Benutzer stammen oder aus nicht vertrauenswürdigen Benutzereingaben erstellt wurden.

  • Danke an @CharlesDuffy für die Erinnerung, den Befehl zu zitieren!

Linux
  1. So weisen Sie einer Variablen die Ausgabe eines Linux-Befehls zu

  2. Wie übergibt man ein Befehlszeilenargument an ein Shell-Skript?

  3. Wie erstelle ich eine temporäre Datei im Shell-Skript?

  4. Wie speichere ich das Ergebnis eines ausgeführten Shell-Befehls in einer Variablen in Python?

  5. Wie setze ich die Umgebungsvariable in GDB mit dem Shell-Befehl?

So führen Sie einen Linux-Shell-Befehl / ein Skript im Hintergrund aus

So verwenden Sie Variablen in Shell-Skripten

So führen Sie einen Shell-Befehl mit Python aus

So erstellen Sie Shell-Skripte

So speichern Sie einen Linux-Befehl als Variable im Shell-Skript

Wie führe ich einen Befehl in einem Shell-Skript aus?