Ne pas utiliser eval
! Il comporte un risque majeur d'introduction d'une 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[@]}"
pour ne pas laisser le IFS
diviser les mots en raison de Word Splitting.
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 indices séparés. Si un tel argument contient des espaces, un guillemetage à l'intérieur lors de l'ajout au tableau empêchera qu'il soit divisé en raison de Word-Splitting.
declare -p cmdArgs
declare -a cmdArgs='([0]="date" [1]="+%H:%M:%S")'
et exécutez les commandes comme
"${cmdArgs[@]}"
23:15:18
(ou) utilisez tous ensemble une fonction bash
pour exécuter la commande,
cmd() {
date '+%H:%M:%S'
}
et appelez la fonction simplement
cmd
POSIX sh
n'a pas de tableaux, donc au mieux, vous pouvez construire une liste d'éléments dans les paramètres positionnels. Voici une manière POSIX sh
de lancer 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 -- "$@" --recipient="$addr"
done
if [ "$first" = 1 ]; then
echo "usage: sendto subject address [address ...]"
return 1
fi
MailTool --subject="$subject" "$@"
}
Remarquez que cette approche ne peut traiter que des commandes simples sans redirections. Elle ne peut pas traiter les redirections, les pipelines, les boucles for/while, les instructions conditionnelles, etc.
Un autre cas d'utilisation courant est celui de l'exécution de curl
avec plusieurs champs d'en-tête et un corps de requête. Vous pouvez toujours définir des arguments comme ci-dessous et invoquer curl
sur le contenu du tableau étendu
curlArgs=('-H' "headerclé: valeur" '-H' "2èmeheaderclé: 2èmevaleur")
curl "${curlArgs[@]}"
Un autre exemple,
payload='{}'
hostURL='http://google.com'
authToken='quelqueToken'
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 correctement citée
curl "${curlCMD[@]}"
15 votes
Utilisez une fonction!
7 votes
Voir ce post : Pourquoi eviter l'utilisation de eval en Bash, et que dois-je utiliser à la place?.
0 votes
Voir aussi Pourquoi l'interpréteur de commandes ignore-t-il les caractères de citation dans les arguments transmis à travers des variables? et le similaire mywiki.wooledge.org/BashFAQ/050