J'ai écrit un script qui peut générer ces arguments pour moi, avec des citations
Si la sortie est correctement citée pour le shell et que vous faites confiance à la sortie , vous pouvez l'exécuter eval
.
En supposant que vous avez un shell qui prend en charge les tableaux, il serait préférable d'en utiliser un pour stocker les arguments que vous obtenez.
Si ./gen_args.sh
produit une sortie comme 'foo bar' '*' asdf
, alors nous pourrions exécuter eval "args=( $(./gen_args.sh) )"
pour remplir un tableau appelé args
avec les résultats. Ce serait les trois éléments foo bar
, *
, asdf
.
Nous pouvons utiliser "${args[@]}"
comme d'habitude pour développer individuellement les éléments du tableau:
$ eval "args=( $(./gen_args.sh) )"
$ for var in "${args[@]}"; do printf ":%s:\n" "$var"; done
:foo bar:
:*:
:asdf:
(Notez que les guillemets "${array[@]}"
s'étendent à tous les éléments en tant qu'arguments distincts non modifiés. Sans guillemets, les éléments du tableau sont sujets au fractionnement des mots. Voir par exemple la page Tableaux sur BashGuide .)
Cependant , eval
exécutera heureusement toutes les substitutions de shell, donc $HOME
dans la sortie s'étendrait à votre répertoire personnel, et une substitution de commande exécuterait en fait une commande dans le shell en cours d'exécution eval
. Une sortie de "$(date >&2)"
créerait un seul élément de tableau vide et afficherait la date actuelle sur stdout. C'est un problème si vous gen_args.sh
obtenez les données d'une source non fiable, comme un autre hôte sur le réseau, des noms de fichiers créés par d'autres utilisateurs. La sortie pourrait inclure des commandes arbitraires. (Si get_args.sh
lui-même était malveillant, il n'aurait besoin de rien produire, il pourrait simplement exécuter directement les commandes malveillantes.)
Une alternative à la citation de shell, qui est difficile à analyser sans eval, serait d'utiliser un autre caractère comme séparateur dans la sortie de votre script. Vous devez en choisir un qui n'est pas nécessaire dans les arguments réels.
Choisissons #
et ayons la sortie du script foo bar#*#asdf
. Nous pouvons maintenant utiliser l' expansion de commande sans guillemets pour diviser la sortie de la commande en arguments.
$ IFS='#' # split on '#' signs
$ set -f # disable globbing
$ args=( $( ./gen_args3.sh ) ) # assign the values to the array
$ for var in "${args[@]}"; do printf ":%s:\n" "$var"; done
:foo bar:
:*:
:asdf:
Vous devrez IFS
reculer plus tard si vous dépendez de la division des mots ailleurs dans le script ( unset IFS
devrait fonctionner pour en faire la valeur par défaut), et également utiliser set +f
si vous souhaitez utiliser la globalisation plus tard.
Si vous n'utilisez pas Bash ou un autre shell qui a des tableaux, vous pouvez utiliser les paramètres de position pour cela. Remplacez args=( $(...) )
par set -- $(./gen_args.sh)
et utilisez "$@"
plutôt "${args[@]}"
qu'alors. (Ici aussi, vous avez besoin de guillemets "$@"
, sinon les paramètres de position sont sujets au fractionnement des mots.)
eval
-être pourrait être utilisé, mais ce n'est généralement pas recommandé.xargs
est aussi quelque chose à considérer