2011-09-23 10 views
16

J'ai un script bash qui reçoit un ensemble de fichiers de l'utilisateur. Ces fichiers sont parfois sous des répertoires avec des espaces dans leurs noms. Malheureusement, contrairement à this question tous les noms de fichiers sont transmis via l'interface de ligne de commande. Supposons que les chemins soient correctement indiqués lorsqu'ils sont passés par l'utilisateur, donc les espaces (sauf pour les espaces entre guillemets) sont des délimiteurs entre les chemins. Comment est-ce que je transmettrais ces paramètres à un sous-programme dans mon script bash d'une manière qui préserve les espaces cités?bash: passer des chemins avec des espaces comme paramètres?

Répondre

19
#! /bin/bash 

for fname in "[email protected]"; do 
    process-one-file-at-a-time "$fname" 
done 

Notez l'utilisation excessive de guillemets. Tout est nécessaire.

En passant tous les arguments à un autre programme est encore plus simple:

process-all-together "[email protected]" 

L'affaire délicate est quand vous voulez diviser les arguments en deux. Cela nécessite beaucoup plus de code dans un simple shell POSIX. Mais peut-être que le Bash a des caractéristiques spéciales.

+0

Merci; Et si je dois les traiter en vrac? – fbrereto

+0

J'ai mis à jour ma réponse. –

+1

Assurez-vous également que le sous-programme double correctement toutes les valeurs, par ex. 'process-un-fichier-à-un-temps() {cp" $ 1 "" backupdir/$ (basename "$ 1") "; } ' –

0
"$var" 

Par exemple,

$ var='foo bar' 

$ perl -E'say "<<$_>>" for @ARGV' $var 
<<foo>> 
<<bar>> 

$ perl -E'say "<<$_>>" for @ARGV' "$var" 
<<foo bar>> 
3

Vous voulez "[email protected]", qui a la syntaxe particulière de l'expansion [email protected] mais en préservant l'espace blanc citant de l'appelant (il ne crée pas une seule chaîne géante avec tous les les arguments dedans). Alors quelqu'un peut appeler votre script comme:

bash-script.sh AFile "Another File With Spaces" 

Ensuite, dans votre script, vous pouvez faire des choses comme:

for f in "[email protected]"; do 
    echo "$f"; 
done 

et obtenir deux lignes de sortie (non 5).

Lisez le paragraphe sur le paramètre spécial "@" ici: http://www.gnu.org/s/bash/manual/bash.html#Special-Parameters

0

Bravo @Roland. Beaucoup pour votre solution

Ça a vraiment marché!

J'ai écrit une fonction de script simple qui ouvre un chemin donné avec nautilus.

Je viens imbriqué une fonction avec cette « aide » -pour boucle dans la fonction principale:

fmp() { 

    fmp2() { 
     nautilus "[email protected]"; 
    }; 

    for fname in "[email protected]"; 
    do   
     fmp2 "$fname";   
    done; 
} 

Maintenant, je suis en mesure de faire tous mes scripts travail manipulant des chemins tout en tournant les dans des fonctions imbriquées enveloppées par une fonction avec cette aide-à-boucle.

Questions connexes