La syntaxe d' extension d'accolade accepte les virgules, mais elle n'accepte pas d'espace après la virgule. Dans de nombreux langages de programmation, les espaces après des virgules sont monnaie courante, mais pas ici. Dans Bash, la présence d'un espace sans guillemets empêche l'expansion de l'accolade.
Retirez l'espace, et cela fonctionnera:
cp ~/some/dir/{my-file-to-rename.bin,new-name-of-file.bin}
Bien que cela ne soit pas du tout requis, notez que vous pouvez déplacer la queue en .bin
dehors des accolades:
cp ~/some/dir/{my-file-to-rename,new-name-of-file}.bin
Si vous souhaitez tester l'effet de l'expansion de l'accolade, vous pouvez utiliser echo
ou printf '%s '
, ou printf
avec la chaîne de format que vous préférez, pour le faire. (Personnellement, je ne l'utilise que echo
pour cela, lorsque je suis dans Bash, car la fonction echo
intégrée de Bash ne développe pas les séquences d'échappement par défaut, et est donc raisonnablement bien adaptée pour vérifier quelle commande sera réellement exécutée.) Par exemple:
ek@Io:~$ echo cp ~/some/dir/{my-file-to-rename,new-name-of-file}.bin
cp /home/ek/some/dir/my-file-to-rename.bin /home/ek/some/dir/new-name-of-file.bin
Bash traite cet espace comme n'importe quel autre. Comme IFS, le séparateur de champ interne. Ceci est utilisé pour le fractionnement des mots après expansion et pour diviser les lignes en mots avec la commande intégrée read.
En insérant le délimiteur, sans échappement, vous avez dit à bash que votre commande et vos arguments sont:
Si vous aviez eu des guillemets ou une échappatoire "\", vous auriez:
Ce qui ne serait pas non plus ce que vous vouliez, sauf si "nouveau-nom-de-fichier.bin" est le nouveau nom de fichier que vous vouliez. Espace inclus. Comme l'expansion de l'accolade se produit en premier, puis l'expansion du tilde, bash s'exécuterait:
Le simple fait de supprimer l'espace réglerait tout cela.
la source
cp ~/some/dir/{my-file-to-rename.bin, new-name-of-file.bin}
etIFS
affecte le résultat. Il n'en est pas de même. Ici, l'espace est un métacaractère de la tokenisation ( étape 2 ). Voir 3.5.7 sur le moment du fractionnement. EssayezIFS=x
alorsprintf '[%s]\n' {a,b}
printf '[%s]\n' {a, b}
printf '[%s]\n' {a,xb}
printf '[%s]\n' {a, xb}
.