web-dev-qa-db-fra.com

Comment passer un paramètre générique à un fichier bash

J'essaie d'écrire un script bash qui permet à l'utilisateur de passer un chemin de répertoire à l'aide de caractères génériques.

Par exemple,

bash show_files.sh *

lorsqu'il est exécuté dans ce répertoire

drw-r--r--  2 root root  4.0K Sep 18 11:33 dir_a
-rw-r--r--  1 root root   223 Sep 18 11:33 file_b.txt
-rw-rw-r--  1 root root   106 Oct 18 15:48 file_c.sql

produirait:

dir_a
file_b.txt
file_c.sql

En l'état actuel, il génère:

dir_a

contenu de show_files.sh:

#!/bin/bash

dirs="$1"

for dir in $dirs
do
    echo $dir
done
31
eisaacson

Le shell parent, celui qui invoque bash show_files.sh *, étend le * pour vous.

Dans votre script, vous devez utiliser:

for dir in "$@"
do
    echo "$dir"
done

Les guillemets doubles garantissent que plusieurs espaces, etc. dans les noms de fichiers sont traités correctement.

Voir aussi Comment parcourir les arguments dans un bash Script shell .


Addendum potentiellement déroutant

Si vous êtes vraiment sûr de vouloir obtenir le script pour développer le *, vous devez vous assurer que * est passé au script (entre guillemets, comme dans les autres réponses), puis assurez-vous qu'il est développé au bon moment dans le traitement (ce qui n'est pas trivial). À ce stade, j'utiliserais un tableau.

names=( $@ )
for file in "${names[@]}"
do
    echo "$file"
done

Je n'utilise pas souvent $@ sans les guillemets, mais c'est une fois où c'est plus ou moins la bonne chose à faire. La partie délicate est qu'il ne gérera pas très bien les caractères génériques avec des espaces.

Considérer:

$ > "double  space.c"
$ > "double  space.h"
$ echo double\ \ space.?
double  space.c double  space.h
$

Ça marche bien. Mais essayez de passer cela en tant que joker au script et ... eh bien, disons simplement que cela devient difficile à ce stade.

Si vous souhaitez extraire $2 séparément, vous pouvez alors utiliser:

names=( $1 )
for file in "${names[@]}"
do
    echo "$file"
done
# ... use $2 ...
47
Jonathan Leffler

Citez le joker:

bash show_files.sh '*'

ou faites accepter à votre script une liste d'arguments, pas un seul:

for dir in "$@"
do
    echo "$dir"
done

Il est préférable d'itérer directement sur "$@' plutôt que de l'attribuer à une autre variable, afin de conserver sa capacité spéciale à contenir des éléments qui contiennent eux-mêmes des espaces.

9
chepner