GNU/Linux >> Tutoriels Linux >  >> Linux

Comment stocker une commande dans une variable dans un script shell ?

Utiliser eval :

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

Ne pas utilisez eval ! Il présente un risque majeur d'introduire l'exécution de code arbitraire.

BashFAQ-50 - J'essaie de mettre une commande dans une variable, mais les cas complexes échouent toujours.

Mettez-le dans un tableau et développez tous les mots avec des guillemets doubles "${arr[@]}" à pas laissez le IFS diviser les mots en raison du fractionnement de mots.

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

et voir le contenu du tableau à l'intérieur. Le declare -p vous permet de voir le contenu du tableau à l'intérieur avec chaque paramètre de commande dans des index séparés. Si l'un de ces arguments contient des espaces, la citation à l'intérieur lors de l'ajout au tableau l'empêchera d'être divisé en raison du fractionnement de mots.

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

et exécutez les commandes comme

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

(ou) utiliser en tout un bash fonction pour exécuter la commande,

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

et appelez la fonction simplement

cmd

POSIX sh n'a pas de tableaux, donc le plus proche que vous pouvez faire est de construire une liste d'éléments dans les paramètres positionnels. Voici un POSIX sh façon d'exécuter un programme de messagerie

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

Notez que cette approche ne peut gérer que des commandes simples sans redirections. Il ne peut pas gérer les redirections, les pipelines, les boucles for/while, les instructions if, etc.

Un autre cas d'utilisation courant est lors de l'exécution de curl avec plusieurs champs d'en-tête et charge utile. Vous pouvez toujours définir des arguments comme ci-dessous et invoquer curl sur le contenu du tableau étendu

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

Un autre exemple,

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

maintenant que les variables sont définies, utilisez un tableau pour stocker vos arguments de commande

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

et maintenant faites une expansion entre guillemets appropriée

curl "${curlCMD[@]}"

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

En utilisant cette méthode, la commande est immédiatement évaluée et sa valeur de retour est stockée.

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

Idem avec 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

Utiliser eval dans le $(...) ne le fera pas évaluer plus tard

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

En utilisant eval, il est évalué lorsque eval est utilisé

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

Dans l'exemple ci-dessus, si vous devez exécuter une commande avec des arguments, placez-les dans la chaîne que vous stockez

stored_date="date -u"
# ...

Pour les scripts bash, cela est rarement pertinent, mais une dernière note. Soyez prudent avec eval . N'évaluez que les chaînes que vous contrôlez, jamais les chaînes provenant d'un utilisateur non approuvé ou créées à partir d'entrées d'utilisateur non approuvées.

  • Merci à @CharlesDuffy de m'avoir rappelé de citer la commande !

Linux
  1. Stockage de la sortie de la commande dans la variable Shell ?

  2. Comment obtenir la propre adresse IP et l'enregistrer dans une variable dans un script shell ?

  3. Comment gérer les commutateurs dans un script shell ?

  4. Comment différer l'expansion variable ?

  5. Comment savoir si la sortie d'une commande ou d'un script shell est Stdout ou Stderr ?

Comment exécuter une commande / un script Linux Shell en arrière-plan

Comment utiliser des variables dans les scripts Shell

Comment exécuter une commande Shell avec Python

Comment créer des scripts shell

Comment stocker une commande Linux en tant que variable dans un script shell

Comment exécuter une commande dans un script shell ?