web-dev-qa-db-fra.com

Variable contenant plusieurs arguments avec des guillemets dans Bash

Je génère une variable bash contenant tous mes arguments et ces arguments contiennent des espaces. Lorsque je lance une commande avec ces arguments - par exemple. ls $ args - les citations ne sont pas interprétées correctement. Voici un exemple - créer et effacer également les fichiers nécessaires.

#!/bin/bash
f1="file n1"
f2="file n2"
# create files
touch "$f1" "$f2"
# concatenate arguments
args="\"$f1\" \"$f2\""
# Print arguments, then launch 'ls' command
echo "arguments :" $args
ls $args
# delete files
rm "$f1" "$f2"

Avec cela, j'ai quelques erreurs "aucun fichier de ce type" pour "fichiern1 ""fichier et n2 "

27
hibou

Vous pourriez envisager d’utiliser un array pour les arguments, comme ceci:

args=( "$f1" "$f2" )
ls "${args[@]}"

(Le problème que vous rencontrez pour le moment est qu'une fois l'interpolation effectuée, il n'y a pas de différence entre les espaces intra et inter-nom de fichier.)

47
martin clayton

Utilisez eval. Cela évaluera d’abord les extensions et les citations, puis exécutera la chaîne résultante comme si elle avait été saisie dans le shell.

args="'$f1' '$f2'"
eval ls $args

eval exécutera alors ls 'file n1' 'file n2'

Avait un problème très similaire, en essayant de passer des arguments dans les variables provenant de /etc/default/ à start_stop_daemon dans les scripts init.

29
Arran Cudbard-Bell

Utilisez set pour définir vos variables en tant que paramètres de position. les guillemets seront conservés si vous y faites référence via "$@" ou "$1", "$2", etc. Veillez à utiliser des guillemets doubles autour des noms de vos variables.

set -- "$f1" "$f2"
touch "$@"
ls "$@"
rm "$@"
4
tripleee

C'est probablement la pire des réponses, mais vous pouvez changer IFS . Ceci est le "séparateur de champ interne" et est égal à espace + tab + nouvelle ligne par défaut.

#!/bin/sh
IFS=,
MAR="-n,my file"
cat $MAR

Le script ci-dessus fonctionnera cat. Le premier argument sera -n (lignes numérotées) et le second argument sera my file.

3
David Grayson

Voici ma recette pour concaténer les arguments cités - principalement utilisés pour garder le script lisible. Mais il est également aisé de commenter facilement certains arguments:

PARAM1="a param with white spaces"
PARAM2="some other funny param"
PARAM3="third spaced param"
#...

PARAMS=$PARAM1
PARAMS+='" "'
PARAMS+=$PARAM2
PARAMS+='" "'
PARAMS+=$PARAM3
#...

eval command '"'$PARAMS'"'
0
bebbo