GNU/Linux >> Linux Esercitazione >  >> Linux

Come memorizzare un comando in una variabile in uno script di shell?

Usa eval:

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

No usa eval ! Ha un grosso rischio di introdurre l'esecuzione di codice arbitrario.

BashFAQ-50 - Sto cercando di inserire un comando in una variabile, ma i casi complessi falliscono sempre.

Mettilo in un array ed espandi tutte le parole con le virgolette "${arr[@]}" non lascia che il IFS dividere le parole a causa della suddivisione delle parole.

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

e vedere il contenuto dell'array all'interno. Il declare -p ti permette di vedere il contenuto dell'array all'interno con ogni parametro di comando in indici separati. Se uno di questi argomenti contiene spazi, le virgolette all'interno durante l'aggiunta all'array eviteranno che venga diviso a causa della divisione delle parole.

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

ed eseguire i comandi come

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

(o) utilizzare del tutto un bash funzione per eseguire il comando,

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

e chiama la funzione come just

cmd

POSIX sh non ha array, quindi il massimo che puoi fare è creare un elenco di elementi nei parametri posizionali. Ecco un POSIX sh modo per eseguire un programma di posta

# 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]"
}

Si noti che questo approccio può gestire solo comandi semplici senza reindirizzamenti. Non può gestire reindirizzamenti, pipeline, cicli for/while, istruzioni if, ecc.

Un altro caso d'uso comune è quando si esegue curl con più campi di intestazione e payload. Puoi sempre definire argomenti come sotto e invocare curl sul contenuto dell'array espanso

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

Un altro esempio,

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

ora che le variabili sono definite, usa un array per memorizzare il tuo comando args

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

e ora esegui una corretta espansione tra virgolette

curl "${curlCMD[@]}"

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

Utilizzando questo metodo, il comando viene immediatamente valutato e il suo valore restituito viene memorizzato.

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

Lo stesso con il 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

Usando eval nel $(...) non lo farà valutare in seguito

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

Utilizzando eval, viene valutato quando eval viene utilizzato

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

Nell'esempio precedente, se devi eseguire un comando con argomenti, inseriscili nella stringa che stai memorizzando

stored_date="date -u"
# ...

Per gli script bash questo è raramente rilevante, ma un'ultima nota. Fai attenzione con eval . Valuta solo le stringhe che controlli, mai le stringhe provenienti da un utente non attendibile o create dall'input di un utente non attendibile.

  • Grazie a @CharlesDuffy per avermi ricordato di citare il comando!

Linux
  1. Come assegnare l'output di un comando Linux a una variabile

  2. Come eseguire un comando memorizzato in una variabile?

  3. Come assegnare l'output di un comando a una variabile di shell?

  4. Come passare un argomento della riga di comando in uno script di shell?

  5. Come creare un file temporaneo nello script della shell?

Come eseguire il comando / script della shell di Linux in background

Come utilizzare le variabili negli script della shell

Come eseguire un comando Shell con Python

Come creare script di shell

Come memorizzare un comando Linux come variabile nello script della shell

Come eseguire un comando in uno script della shell?