Pourquoi wc <<< «$ string» affiche une longueur d'un octet plus longue que printf «$ string» | toilettes?

11

Par accident, j'ai découvert que cela wccompte différemment selon la façon dont il obtient l'entrée de bash:

$ s='hello'
$ wc -m <<<"$s"
6
$ wc -c <<<"$s"
6
$ printf '%s' "$s" | wc -m
5
$ printf '%s' "$s" | wc -c
5

Ce comportement - à mon humble avis - est-il documenté quelque part? Qu'est-ce qui wccompte ici - est-ce une nouvelle ligne supposée?

rexkogitans
la source
3
Vous pouvez toujours diriger pour od -cvoir exactement ce que vous avez.
Thorbjørn Ravn Andersen
Ou mieux encore xxd -g1.
Ruslan
1
J'espère que ce printf "$s"n'est pas votre script réel ... j'espère que vous vouliez direprintf "%s" "$s"
user541686
Puisqu'il y avait tellement de commentaires sur printf, j'ai édité mon article pour refléter les meilleures pratiques.
rexkogitans

Réponses:

38

La différence est causée par une nouvelle ligne ajoutée à la chaîne here. Voir le manuel de Bash :

Le résultat est fourni sous la forme d'une chaîne unique, avec une nouvelle ligne ajoutée, à la commande sur son entrée standard (ou descripteur de fichier n si n est spécifié).

wc compte de la même manière, mais son entrée est différente.

Stephen Kitt
la source
7
Si il convient de noter que pour imprimer le contenu (arbitraire) d'une variable sans caractère de nouvelle ligne ajouté, ce devrait être printf %s "$var"(ou print -rn -- "$var"avec des shells de type ksh), printf "$var"ce qui ne fonctionnerait pas correctement pour les valeurs de $varce contenant %ou des barres obliques inverses (ou commencer par la -plupart des implémentations).
Stéphane Chazelas
Notez que l'implémentation ici-chaîne d'origine dans le port Unix rcn'a pas ajouté ce caractère de nouvelle ligne.
Stéphane Chazelas
26

C'est une nouvelle ligne suivante ajoutée par le redirecteur here-string:

$ s="hello"
$ hexdump -C <<<"$s"
00000000  68 65 6c 6c 6f 0a                                 |hello.|
00000006
$ printf "$s" | hexdump -C
00000000  68 65 6c 6c 6f                                    |hello|
00000005
Murphy
la source