¿Por qué wc <<< “$ string” muestra una longitud de un byte más larga que printf “$ string” | ¿baño?

11

Accidentalmente, descubrí que wccuenta de manera diferente dependiendo de cómo obtiene la entrada de bash:

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

¿Es esto, en mi humilde opinión, un comportamiento documentado en alguna parte? ¿Qué wccuenta aquí? ¿Es esta una nueva línea asumida?

rexkogitans
fuente
3
Siempre puedes canalizar para od -cver exactamente lo que tienes.
Thorbjørn Ravn Andersen
O mejor xxd -g1.
Ruslan
1
Esperanza que printf "$s"no es su guión real ... espero que quería decirprintf "%s" "$s"
user541686
Como había tantos comentarios sobre printf, edité mi publicación para reflejar las mejores prácticas.
rexkogitans

Respuestas:

38

La diferencia es causada por una nueva línea agregada a la cadena aquí. Ver el manual de Bash :

El resultado se proporciona como una sola cadena, con una nueva línea adjunta, al comando en su entrada estándar (o descriptor de archivo n si se especifica n ).

wc está contando de la misma manera, pero su entrada es diferente.

Stephen Kitt
fuente
77
Si se debe tener en cuenta que para imprimir el contenido (arbitrario) de una variable sin un carácter de nueva línea agregado, debería ser printf %s "$var"(o print -rn -- "$var"con shells tipo ksh), printf "$var"que no funcionaría correctamente para los valores $varque contienen %caracteres de barra diagonal inversa (o comenzar con la -mayoría de las implementaciones).
Stéphane Chazelas
Tenga en cuenta que la implementación original de cadena aquí en el puerto Unix de rcno agregó ese carácter de nueva línea.
Stéphane Chazelas
26

Es una nueva línea exitosa agregada por el redirector 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
fuente