¿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 $SHELLy 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

cshNo es una cáscara de bourne.tcshno es uno cualquiera (que escshcon algunos errores corregidos)$SHELLes el shell preferido del usuario, como$EDITORes su editor de texto preferido. Tiene poco que ver con el shell actualmente en ejecución.evalIndicar la salida de$SHELL --versioncódigo shell no tiene sentido.Respuestas:
Suponiendo que usted quiere restringir a Bourne como conchas (muchas otras cáscaras como
csh,tcsh,rc,esofishmatrices 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 comokshen la mayoría de las unidades comerciales tradicionales donde también es la basesh)set -A array foo baroset -A array -- "$var" ...si no puede garantizar que$varno comenzará con una-o+.0.a[1]=value.a[5]=foofuncionará 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). El5puede 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}" ]]).$aes el mismo que${a[0]}. Es decir, las matrices de alguna manera extienden las variables escalares dándoles valores adicionales.pdkshy derivados (esa es la base para,kshy algunas veces,shde 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
ksh88pero 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.mkshtienen unos pocos operadores adicionales inspiradosbash,ksh93ozshcomo asignaciones a laa=(x y),a+=(z),${!a[@]}para obtener la lista de índices asignados.zsh.zshmatrices están generalmente mejor diseñados y toman lo mejor dekshycshmatrices. Son similareskshpero con diferencias significativas:kshemulación), eso es consistente con la matriz Bourne (los parámetros de posición $ @, quezshtambién se exponen como su matriz $ argv) y lascshmatrices.$ano 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]=1funciona 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 ytambién funciona, peroset -A a -- x yno 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) ykshdeSolaris 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.bashes la cáscara del proyecto GNU. Se usa comoshen versiones recientes de OS / X y algunas distribuciones de GNU / Linux.bashLas matrices emulan principalmenteksh88las que tienen algunas características deksh93yzsh.a=(x y)soportado.set -A a x yNo 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 deksh93yzsh.bashversiones 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 azsha=(var value)arrayincorporadoarray -s a 5 valuepara 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
perlo 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
zshmatrices para que se parezcan más a laskshmatrices en ámbitos locales (en funciones o funciones anónimas).También puede emular
ksh(mejorar la compatibilidad conkshmatrices y varias otras áreas) con:Con esto en mente y que está dispuesto a soltar para
yashyksh88y versiones anteriores depdkshderivados, y siempre y cuando no se intenta crear matrices dispersas, que deben ser capaces de utilizar de manera uniforme:a[0]=fooa=(foo bar)(pero noa=())"${a[#]}"`"${a[@]}"`"${a[0]}"en aquellas funciones que tienen
emulate -L ksh, mientras elzshusuario todavía usa sus matrices normalmente de la manera zsh.fuente
Puede usar
evalpara probar la sintaxis de la matriz:fuente
ksh88admite 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]=1peroarray -s a 5 1ksh93compuesta me sorprendió, ¿te importaría darme parte de la documentación al respecto? Añado1a la matriz para que funcione.