Expande las pruebas
Esencialmente, el shell es un tipo de lenguaje macro, o al menos un híbrido o algún tipo. Cada línea de comando se puede dividir básicamente en dos partes: la parte de análisis / entrada y la parte de expansión / salida.
La primera parte es en lo que la mayoría de la gente se enfoca porque es la más simple: ves lo que obtienes. La segunda parte es lo que muchos evitan incluso tratar de entender muy bien y es por qué la gente dice que las cosas eval
son malas y siempre citan sus expansiones : la gente quiere que el resultado de la primera parte sea igual a la primera. Eso está bien, pero conduce a ramificaciones de código innecesariamente largas y toneladas de pruebas extrañas.
Las expansiones son de autoevaluación . Los ${param[[:]#%+-=?]word}
formularios son más que suficientes para validar el contenido de un parámetro, son anidables y se basan en la evaluación de NUL , que es lo que la mayoría de la gente espera de las pruebas de todos modos. +
puede ser especialmente útil en bucles:
r()while IFS= read -r r&&"${r:+set}" -- "$@" "${r:=$*}";do :;done 2>&-
IFS=x
printf %s\\n some lines\ of input here '' some more|{ r;echo "$r"; }
somexlines ofxinputxhere
... mientras read
las líneas no en blanco se "${r:+set}"
expanden "set"
y las posiciones se $r
agregan. Pero cuando una línea en blanco es read
, $r
está vacía y se "${r:+set}"
expande a ""
, que es un comando no válido. Pero debido a que la línea de comandos se expande antes de la ""
se busca comando nulo, "${r:=$*}"
toma los valores de todos los posicionales concatenados en el primer byte $IFS
también. r()
podría llamarse nuevamente en un |{
comando compuesto ;}
con un valor diferente para $IFS
obtener el siguiente párrafo de entrada, ya que es ilegal que un shell se almacene read
más allá de la siguiente \n
línea de entrada.
sh
y qué shell permite estafor
sintaxis? está expresamente permitido enzsh
.sh
y que Bash también lo permite por eso, aunque lamentablemente no tengo una cita.csh
, probablemente, así es como trabajaron en ese caparazón.ksh93
lo anterior podría ser:;{1..10}
y enbash
:printf %s\\n {1..10}
for((;i++<10)){ echo $i;}
es más corto quefor i in {1..10};{ echo $i;}