¿Hay una manera concisa de probar el soporte de matriz por el shell local similar a Bourne en la línea de comando?
Esto siempre es posible:
$ arr=(0 1 2 3);if [ "${arr[2]}" != 2 ];then echo "No array support";fi
o prueba $SHELL
y versión de shell:
$ eval $(echo "$SHELL --version") | grep version
y luego leyendo la página del manual, suponiendo que tenga acceso a ella. (Incluso allí, escribiendo desde /bin/bash
, estoy asumiendo que todos los proyectiles tipo Bourne admiten la opción larga --version
, cuando eso se rompe para ksh, por ejemplo ).
Estoy buscando una prueba simple que pueda ser desatendida e incorporada en una sección de Uso al comienzo del script o incluso antes de llamarla.
shell-script
shell
array
Cbhihe
fuente
fuente
csh
No es una cáscara de bourne.tcsh
no es uno cualquiera (que escsh
con algunos errores corregidos)$SHELL
es el shell preferido del usuario, como$EDITOR
es su editor de texto preferido. Tiene poco que ver con el shell actualmente en ejecución.eval
Indicar la salida de$SHELL --version
código shell no tiene sentido.Respuestas:
Suponiendo que usted quiere restringir a Bourne como conchas (muchas otras cáscaras como
csh
,tcsh
,rc
,es
ofish
matrices de apoyo, pero escribir un guión compatible al mismo tiempo a Bourne como conchas y los que es complicado y generalmente tiene sentido, ya que son intérpretes para completamente diferente y idiomas incompatibles), tenga en cuenta que existen diferencias significativas entre las implementaciones.Los shells tipo Bourne que admiten matrices son:
ksh88
(esa es la primera implementación de matrices, ksh88 todavía se encuentra comoksh
en la mayoría de las unidades comerciales tradicionales donde también es la basesh
)set -A array foo bar
oset -A array -- "$var" ...
si no puede garantizar que$var
no comenzará con una-
o+
.0
.a[1]=value
.a[5]=foo
funcionará incluso sia[0,1,2,3,4]
no están configurados y los dejará sin configurar.${a[5]}
para acceder al elemento del índice 5 (no necesariamente el sexto elemento si la matriz es escasa). El5
puede haber cualquier expresión aritmética.${#a[@]}
es el número de elemento asignado en la matriz (no el mayor índice asignado).[[ -n "${a[i]+set}" ]]
).$a
es el mismo que${a[0]}
. Es decir, las matrices de alguna manera extienden las variables escalares dándoles valores adicionales.pdksh
y derivados (esa es la base para,ksh
y algunas veces,sh
de varios BSD y fue la única implementación de código abierto de ksh antes de que se liberara la fuente de ksh93):Principalmente como
ksh88
pero tenga en cuenta:set -A array -- foo bar
(--
no era necesario allí).${#a[@]}
es uno más el índice del mayor índice asignado. (a[1000]=1; echo "${#a[@]}"
salidas 1001 a pesar de que la matriz tiene solo un elemento.mksh
tienen unos pocos operadores adicionales inspiradosbash
,ksh93
ozsh
como asignaciones a laa=(x y)
,a+=(z)
,${!a[@]}
para obtener la lista de índices asignados.zsh
.zsh
matrices están generalmente mejor diseñados y toman lo mejor deksh
ycsh
matrices. Son similaresksh
pero con diferencias significativas:ksh
emulación), eso es consistente con la matriz Bourne (los parámetros de posición $ @, quezsh
también se exponen como su matriz $ argv) y lascsh
matrices.$a
no es lo mismo${a[0]}
pero se expande a los elementos no vacíos de la matriz ("${a[@]}"
para todos los elementos como enksh
).a[5]=1
funciona pero asigna todos los elementos del 1 al 4 a la cadena vacía si no se asignaron. Entonces${#a[@]}
(igual${#a}
que en ksh es el tamaño del elemento del índice 0) es el número de elementos en la matriz y el índice asignado más grande.a=(x y)
.set -A a x y
también funciona, peroset -A a -- x y
no es compatible a menos que en la emulación ksh (--
no se necesita en la emulación zsh).ksh93
. (Aquí se describen las últimas versiones).ksh93
, considerado experimental durante mucho tiempo, ahora se puede encontrar en más y más sistemas ahora que se ha lanzado como FOSS. Por ejemplo, es el/bin/sh
(donde reemplazó el shell Bourne/usr/xpg4/bin/sh
, el shell POSIX todavía se basa enksh88
) yksh
deSolaris 11
. Sus matrices amplían y mejoran los ksh88.a=(x y)
se puede usar para definir una matriz, pero comoa=(...)
también se usa para definir variables compuestas (a=(foo=bar bar=baz)
),a=()
es ambigua y declara una variable compuesta, no una matriz.a=((0 1) (0 2))
) y los elementos de la matriz también pueden ser variables compuestas (a=((a b) (c=d d=f)); echo "${a[1].c}"
).a=([2]=foo [5]=bar)
puede usar una sintaxis para definir matrices dispersas a la vez.zsh
, pero gran cantidad de operadores soportados también para manipular matrices."${!a[@]}"
para recuperar la lista de índices de matriz.bash
.bash
es la cáscara del proyecto GNU. Se usa comosh
en versiones recientes de OS / X y algunas distribuciones de GNU / Linux.bash
Las matrices emulan principalmenteksh88
las que tienen algunas características deksh93
yzsh
.a=(x y)
soportado.set -A a x y
No es compatible.a=()
crea una matriz vacía (sin variables compuestasbash
)."${!a[@]}"
para la lista de índices.a=([foo]=bar)
sintaxis compatible, así como algunos otros deksh93
yzsh
.bash
versiones recientes también admiten matrices asociativas como un tipo separado.yash
. Es una implementación POSIX sh relativamente reciente, limpia y con reconocimiento de varios bytes. No en uso amplio. Sus matrices son otra API limpia similar azsh
a=(var value)
array
incorporadoarray -s a 5 value
para modificar el 5 º elemento fallaría si ese elemento no fue asignado de antemano.${a[#]}
,${#a[@]}
siendo el tamaño de los elementos como una lista.a=("$a")
redefinir una variable escalar como una matriz antes de poder agregar o modificar elementos.sh
.Entonces, a partir de eso, puede ver que la detección de soporte de matriz, que podría hacer con:
no es suficiente para poder usar esas matrices. Debería definir comandos de envoltura para asignar matrices como elementos completos e individuales, y asegurarse de no intentar crear matrices dispersas.
Me gusta
Y luego se accede a elementos de la matriz con
"${a[$first_indice+n]}"
, toda la lista con"${a[@]}"
y utilizar las funciones de contenedor (array_elements
,set_array
,set_array_element
) para obtener el número de elementos de un array (en$REPLY
), establecer la matriz como enteros o asignar un elementos individuales.Probablemente no valga la pena el esfuerzo. Que haría uso
perl
o límite a la matriz shell Bourne / POSIX:"$@"
.Si la intención es que el shell interactivo de un usuario obtenga algún archivo para definir funciones que utilizan arrays internamente, aquí hay algunas notas más que pueden ser útiles.
Puede configurar las
zsh
matrices para que se parezcan más a lasksh
matrices en ámbitos locales (en funciones o funciones anónimas).También puede emular
ksh
(mejorar la compatibilidad conksh
matrices y varias otras áreas) con:Con esto en mente y que está dispuesto a soltar para
yash
yksh88
y versiones anteriores depdksh
derivados, y siempre y cuando no se intenta crear matrices dispersas, que deben ser capaces de utilizar de manera uniforme:a[0]=foo
a=(foo bar)
(pero noa=()
)"${a[#]}"
`"${a[@]}"
`"${a[0]}"
en aquellas funciones que tienen
emulate -L ksh
, mientras elzsh
usuario todavía usa sus matrices normalmente de la manera zsh.fuente
Puede usar
eval
para probar la sintaxis de la matriz:fuente
ksh88
admite matrices pero noa=()
. Enksh93
,a=()
declara una variable compuesta, no una matriz, a menos que la variable se haya declarado previamente como una matriz.yash
, no lo hacesa[5]=1
peroarray -s a 5 1
ksh93
compuesta me sorprendió, ¿te importaría darme parte de la documentación al respecto? Añado1
a la matriz para que funcione.