Puede llamar a utilidades externas (vea otras respuestas), pero harán que su secuencia de comandos sea más lenta y es difícil hacer la instalación correcta.
Zsh
En zsh, puede escribir ${#$(readlink -f /etc/fstab)}
para obtener la duración de la sustitución del comando. Tenga en cuenta que esta no es la longitud de la salida del comando, es la longitud de la salida sin ninguna nueva línea final.
Si desea la longitud exacta de la salida, muestre un carácter adicional que no sea de nueva línea al final y reste uno.
$((${#$(readlink -f /etc/fstab; echo .)} - 1))
Si lo que desea es la carga útil en la salida del comando, entonces debe restar dos aquí, porque la salida de readlink -f
es la ruta canónica más una nueva línea.
$((${#$(readlink -f /etc/fstab; echo .)} - 2))
Esto difiere del ${#$(readlink -f /etc/fstab)}
caso raro pero posible en el que el camino canónico termina en una nueva línea.
Para este ejemplo específico, no necesita una utilidad externa en absoluto, porque zsh tiene una construcción incorporada que es equivalente a readlink -f
través del modificador de historial A
.
echo /etc/fstab(:A)
Para obtener la longitud, use el modificador de historial en una expansión de parámetros:
${#${:-/etc/fstab}:A}
Si tiene el nombre del archivo en una variable filename
, sería ${#filename:A}
.
Conchas de estilo Bourne / POSIX
Ninguno de los shells Bourne / POSIX puros (Bourne, ash, mksh, ksh93, bash, yash ...) tiene una extensión similar que yo sepa. Si necesita aplicar una sustitución de parámetros a la salida de una sustitución de comando o anidar sustituciones de parámetros, utilice etapas sucesivas.
Puede rellenar el procesamiento en una función si lo desea.
command_output_length_sans_trailing_newlines () {
set -- "$("$@")"
echo "${#1}"
}
o
command_output_length () {
set -- "$("$@"; echo .)"
echo "$((${#1} - 1))"
}
pero generalmente no hay beneficio; excepto con ksh93, eso hace que una bifurcación adicional pueda usar la salida de la función, por lo que hace que su script sea más lento y rara vez hay algún beneficio de legibilidad.
Una vez más, la salida de readlink -f
es la ruta canónica más una nueva línea; si desea la longitud del camino canónico, reste 2 en lugar de 1 pulg command_output_length
. El uso command_output_length_sans_trailing_newlines
da el resultado correcto solo cuando la ruta canónica en sí misma no termina en una nueva línea.
Bytes vs caracteres
${#…}
se supone que es la longitud en caracteres, no en bytes, lo que hace la diferencia en configuraciones regionales multibyte. Las versiones razonablemente actualizadas de ksh93, bash y zsh calculan la longitud en caracteres de acuerdo con el valor de LC_CTYPE
en el momento en que ${#…}
se expande la construcción. Muchos otros shells comunes realmente no admiten configuraciones regionales multibyte: a partir del guión 0.5.7, mksh 46 y posh 0.12.3, ${#…}
devuelve la longitud en bytes. Si desea la longitud en caracteres de manera confiable, use la wc
utilidad:
$(readlink -f /etc/fstab | wc -m)
Siempre que $LC_CTYPE
designe una configuración regional válida, puede estar seguro de que esto se eliminará por error (en una plataforma antigua o restringida que no admite configuraciones regionales de varios bytes) o devolverá la longitud correcta en caracteres. (Para Unicode, "longitud en caracteres" significa la cantidad de puntos de código; la cantidad de glifos es otra historia, debido a complicaciones como la combinación de caracteres).
Si desea la longitud en bytes, establezca LC_CTYPE=C
temporalmente o use en wc -c
lugar de wc -m
.
El conteo de bytes o caracteres wc
incluye cualquier nueva línea final del comando. Si desea la longitud de la ruta canónica en bytes, es
$(($(readlink -f /etc/fstab | wc -c) - 1))
Para obtenerlo en caracteres, resta 2.
readlink -f /etc/fstab
es de 11 caracteres. No olvides la nueva línea. De lo contrario, verías/etc/fstabluser@cern:~$
cuándo lo ejecutaste desde un caparazón.