J'ai fait un script où j'ai écrit:
COMMAND = "/ usr/bin/exiftool $ PATH_NAME" .... code .... $ COMMAND
La variable $ PATH_NAME est assignée dynamiquement dans une boucle while. La commande fonctionne correctement jusqu'à ce qu'elle rencontre des fichiers contenant des espaces (par exemple, PATH_NAME = "Add Driver.png"). La sortie de la console est:
Fichier non trouvé: ./Add Fichier non trouvé: driver.png
La commande devrait être:
/ usr/bin/exiftool ./Add driver.png
Je pense que le problème est donné par les espaces dans le $ PATH_NAME. J'ai aussi essayé d'exécuter directement la commande:
eval "/ usr/bin/exiftool $ PATH_NAME"
Mais même erreur de sortie. Une idée pour résoudre le problème? Merci.
Au lieu d'utiliser des chaînes simples, construisez votre commande en utilisant des tableaux. Les tableaux fournissent une interface pratique: Si a
est un tableau, alors "${a[@]}"
(notez les guillemets) se développe en chaque élément de a
, sans le fractionnement ou l’agrégation de champ supplémentaire (pour que les espaces, ainsi que les caractères génériques), intact).
Exemple:
$ a=(printf "|%s|\n" "foo bar" "*")
$ echo ${a[@]}
printf |%s|\n foo bar bin boot dev etc home lib lib64 lost+found mnt opt proc root run sbin srv sys tmp usr var
Notez comment le *
a été développé et comment les espaces supplémentaires entre foo
et bar
ont été perdus. Mais avec le "${a[@]}"
, ceux-ci sont conservés:
$ echo "${a[@]}"
printf |%s|\n foo bar *
C'est idéal pour construire des commandes. Maintenant, vous pouvez faire:
$ "${a[@]}"
|foo bar|
|*|
Voir? Les arguments ont été parfaitement conservés.
Alors faites:
COMMAND=(/usr/bin/exiftool "$PATH_NAME")
"${COMMAND[@]}"
Pour des explications plus détaillées sur la façon dont Bash interprète les espaces, je vous recommande de lire ceci: Variables Bash et substitution de commandes
Solution propre
L'élargissement d'une variable peut entraîner des résultats inattendus et parfois catastrophiques si la variable contient des caractères spéciaux:
user@Host:~$ do_something $some_variable
L'élargissement d'une variable entre guillemets peut éviter de tels problèmes:
user@Host:~$ do_something "$some_variable"
Explication
Le cas rencontré ici est décrit à la fin du post:
Les dangers des variables non citées
Dans un monde idéal, tout le monde garderait ses valeurs de chaîne courtes et sans espace/nouvelle ligne, ni aucun autre caractère spécial.
[...]
Mais lorsque les gens commencent à ajouter des caractères spéciaux aux noms de fichiers, tels que des espaces, le développement de variables, sans l'utilisation de guillemets doubles, peut s'avérer dangereux.
[...]
La principale chose à retenir ici est donc: double-citez vos références de variable autant que possible .
le point de Glenn Jackman est bien pris. Mais, pour résoudre votre cas d'utilisation immédiate, qu'en est-il des backticks? Ainsi:
`echo $COMMAND`
Par exemple, cela fonctionne:
COMMAND='ls /'
`echo $COMMAND`