Les paramètres fish sont, en règle générale, échappés avant d'être injectés dans les commandes fish :
mqudsi@freebsd> echo hello > hello\ world.txt
mqudsi@freebsd> file (echo hello world.txt)
hello world.txt: ASCII text
Cependant, le résultat de l'expansion des accolades n'est pas correctement échappé, _et_ il n'y a pas de moyen facile d'échapper pour l'échapper manuellement car l'introduction de guillemets autour du paramètre interrompt l'expansion :
mqudsi@freebsd> echo -n hello\ {1,2,3}.txt\n
hello 1.txt
hello 2.txt
hello 3.txt
Comme vous pouvez le voir, après le premier paramètre, echo
est passé à deux arguments distincts hello
et #.txt
, conduisant à l'espace supplémentaire devant les mots.
Envelopper les arguments entre guillemets conduit à ce qui suit :
mqudsi@freebsd> echo -n "hello\ {1,2,3}.txt\n"
hello\ {1,2,3}.txt\n
Tout en essayant de contourner le problème en insérant des guillemets échappés dans la chaîne d'origine (en supposant que le contenu de la chaîne n'est pas échappé après le remplacement et avant l'injection), les guillemets sont correctement échappés, empêchant le résultat souhaité :
mqudsi@freebsd> echo -n \"hello\ {1,2,3}.txt\n\" "hello 1.txt " "hello 2.txt " "hello 3.txt
"
Il semble que l'expansion des paramètres se produise après l'étape de division des arguments.
echo
est passé à deux arguments séparés hello et #.txt, conduisant à l'espace supplémentaire devant les mots.
Je ne suis pas d'accord avec ce diagnostic. echo
reçoit 3 arguments (chacun se terminant par \n
), que echo
imprime consciencieusement avec un espace entre les deux. Je ne vois aucun bug ici.
Voici ce que je fais pour déboguer les arguments :
~> printf '«%s»' hei\ {1,2,3}.txt\n
«hei 1.txt
»«hei 2.txt
»«hei 3.txt
»⏎
Voici ce que je fais pour déboguer les arguments :
J'utilise string escape
, c'est-à-dire
> string escape -- hello\ {1,2,3}.txt\n
hello\ 1.txt\n
hello\ 2.txt\n
hello\ 3.txt\n
ce qui signifie que vous obtenez réellement ce que j'attends. Vous obtenez l'argument complet avec "1", puis avec "2" et enfin avec "3". Il se trouve que l'argument complet inclut une nouvelle ligne.
@mqudsi : Je suppose que ce qui vous
(command)
) sur la nouvelle ligne. Cela signifie que le \n
ici n'a aucune signification particulière après avoir été remplacé par un caractère de nouvelle ligne. C'est "un personnage", pour le reste. Nous n'avons pas besoin d'_échapper_ au personnage, nous n'effectuons simplement pas le fractionnement.Ou dans file (echo hello world.txt)
, le "hello world.txt" _n'est pas_ échappé en hello\ world.txt
, il n'est tout simplement pas divisé car il n'y a pas de nouvelle ligne. Si vous avez un fichier appelé hello\nworld.txt
, cela aurait des problèmes similaires au problème de bash avec les espaces.
echo
insère des espaces entre ses arguments (si "-s" n'a pas été donné). C'est ce qui cause l'indentation étrange - parce que les espaces se produisent juste après la nouvelle ligne.Cela signifie que si vous voulez avoir la sortie
hello 1.txt
hello 2.txt
hello 3.txt
utilisez echo -s
ou printf '%s\n' hello\ {1,2,3}.txt
.
Je pense qu'il s'agit d'un malentendu plutôt que d'un bug. Ai-je raison?
Désolé, les gars ! J'essayais de trouver une reproduction minimale pour un problème et j'étais confus par quelque chose de complètement différent. Je me suis trompé sur le comportement de l'expansion des paramètres, en particulier, je l'ai confondu avec celui de parallel
ou xargs
avec une limite de 1, c'est-à-dire que j'ai supposé que echo {1,2,3}
s'étendrait à 3 commandes avec 1 argument chacune et non 1 commande avec 3 arguments.
Merci de m'avoir corrigé.