2009-01-04 6 views
8

Dans bash, on peut échapper des arguments contenant des espaces.construire des listes d'arguments contenant des espaces blancs

foo "a string" 

Cela fonctionne également pour les arguments à une commande ou une fonction:

bar() { 
    foo "[email protected]" 
} 

bar "a string" 

Jusqu'à présent, si bon, mais si je veux manipuler les arguments avant d'appeler foo?

Cela ne fonctionne pas:

bar() { 
    for arg in "[email protected]" 
    do 
     args="$args \"prefix $arg\"" 
    done 

    # Everything looks good ... 
    echo $args 

    # ... but it isn't. 
    foo $args 

    # foo "$args" would just be silly 
} 

bar a b c 

Alors, comment voulez-vous construire une liste d'arguments lorsque les arguments contiennent des espaces?

Répondre

13

Il y a (au moins) deux façons de le faire:

(1.) Utilisez un tableau et décompresser à l'aide "${array[@]}":

bar() { 
    local i=0 args=() 
    for arg in "[email protected]" 
    do 
     args[$i]="prefix $arg" 
     ((++i)) 
    done 

    foo "${args[@]}" 
} 

Alors qu'avons-nous appris? "${array[@]}" à ${array[*]} ce "[email protected]" à $*.

(2.) ou si vous ne voulez pas utiliser des tableaux que vous devez utiliser eval:

bar() { 
    local args=() 
    for arg in "[email protected]" 
    do 
     args="$args \"prefix $arg\"" 
    done 

    eval foo $args 
} 
+0

putain, aurait dû être arrivé plus tôt - aurait pu vous épargner le travail :) – hop

2

Utilisez arrays (l'un des hidden features dans Bash).

+1

comment exactement? J'ai mis à jour ma question avec une tentative d'utilisation d'un tableau - qui n'a pas fonctionné. – tarsius

+0

Il ne semble pas y avoir un moyen facile de passer des tableaux à des fonctions (qui sont vraiment des sous-clichés). Vous auriez besoin de les citer et de les passer comme argument régulier (comme vous le feriez pour toute autre commande). – JesperE

0

Vous pouvez utiliser les tableaux comme vous le suggérez, avec un petit détail changé. La ligne qui appelle foo doit indiquer

foo "${args[@]}" 
0

J'ai également eu un problème avec ceci. J'écrivais un script bash pour sauvegarder les fichiers importants sur mon ordinateur Windows (cygwin). J'ai aussi essayé l'approche du tableau, et j'avais encore quelques problèmes. Je ne sais pas exactement comment je l'ai réparé, mais voici les parties de mon code qui sont importantes au cas où cela vous aiderait.

WORK="d:\Work Documents\*" 
# prompt and 7zip each file 
for x in $SVN $WEB1 $WEB2 "$WORK" $GRAPHICS $W_SQL 
do 
    echo "Add $x to archive? (y/n)" 
    read DO 
    if [ "$DO" == "y" ]; then 
     echo "compressing $x" 
     7zip a $W_OUTPUT "$x" 
    fi 
    echo "" 
done 
3

Voici une version plus courte: (par exemple des arguments de construction à une commande find)

dir=$(shift) 
for f in "[email protected]" ; do 
    args+=(-iname "*$f*") 
done 
find "$dir" "${args[@]}" 
Questions connexes