Estoy intentando crear una función y creo que encontré un buen ejemplo funcional, pero no entiendo toda la lógica detrás de ella.
Más específicamente, en la línea "mientras", ¿alguien podría explicar qué es y qué hace la prueba? ¿Qué es $# (¿no es # un carácter de comentario?) y ¿de dónde proviene el parámetro -gt 0? No pude encontrarlo en la página de manual while.
Aquí está el ejemplo:
function my_function()
{
while test $# -gt 0
do
$
echo "$1"
shift
done
}
Gracias.
Respuesta1
Si bien #
por sí solo es definitivamente un comentario, $#
contiene la cantidad de parámetros pasados a su función.
test
es un programa que te permite realizar varias pruebas, por ejemplo, si un número es mayor que otro (si tu operador es -gt
; hay muchos otros operadores, ver man test
). Devolverá éxito si la prueba es exitosa (en este caso, si the number of parameters
ES mayor que 0).
el shift
comando descarta el primer parámetro. También disminuye$#
El código en su conjunto puede verse como: hacer algo con un parámetro (en este caso, mostrarlo en la pantalla), luego descartarlo; repita hasta que no queden parámetros.
Si desea ver todos los parámetros que quedan, útiles para la depuración, verifique el contenido de$@
Respuesta2
$#
==> parámetros de script pasados
test
==> comando de evaluación de condición
-gt
==> representamas grande que
test a -gt b
==> verdadero si a es mayor que b, falso en caso contrario
Poniendolo todo junto:
while test $# -gt 0
==> mientras se pasan más parámetros (la razón por la que esto está cambiando es debido al cambio)
Lo que complica las cosas está shift
dentro del cuerpo del bucle while.
$1
==> representa siempre el primer parámetro
Para hacer esto más concreto, digamos que está pasando parámetros a
y .b
c
$1
==> representa a
ya que este es su primer parámetro
al llamar a now shift
, a
desapareció y su lista de parámetros es ahora b
y, c
por lo tanto, si invoca $1
ahora es b
porque este es ahora el primer parámetro de la lista. Invocando shift
una vez más su lista de parámetros ahora es solo c
, por lo tanto $1
es ahora c
. Llamar shift
una vez más deja la lista de parámetros vacía, por lo tanto, la condición while no tendrá éxito (ya que la lista de parámetros ya no es mayor que 0, ya que ahora tiene un tamaño cero), lo que hará que finalice el ciclo while.
¿Cuáles son las ventajas de utilizar shift
y hacer referencia al parámetro actual como $1
?
Le brinda la flexibilidad de no saber de antemano en su script cuántos parámetros se pasan en el script y, independientemente de eso, iterarlos uno por uno refiriéndose dentro del bucle while al parámetro actual siempre, ya $1
que eso significa el encabezado del lista de parámetros. Al shift
hacer ing, eventualmente la lista de parámetros estará vacía, por lo tanto, es importante tener la condición while para verificar si es mayor que cero para terminar y no realizar un bucle infinito.
Respuesta3
Ejecute el siguiente script para comprender qué significan las variables. Guarde el script como somescript.sh
y llámelo con algunos parámetros de entrada.
#!/bin/bash
echo "I display the total parameters passed to this script from commandline"
echo $#
echo "I display all the parameter values"
echo "Input: $@"
echo "I display the first parameter value"
echo "$1"
shift
echo "After shift: $@"
Respuesta4
Si me perdona un poco de reciclaje de respuestas, creo que esto puede resultarle útil.
_fn() { set -- "$@" $(cat)
while ${1+:} false ; do
echo "$1" && [ "$1" = "arg2" ] && echo "$1"
$YOUR_CHK
shift
done
}
echo "arg2" | _fn "arg1"
PRODUCCIÓN
arg1
arg2
arg2
Eso maneja tanto los argumentos de la línea cmd como stdin
. Solo ejecuta el while
bucle para verificarlos mientras todavía tiene al menos un argumento guardado en su matriz de parámetros. Descarta todos los argumentos que verifica, por lo que parte de ello $YOUR_CHK
debería ser guardar información que considere valiosa de una forma u otra.
_fn
se comportaría igual si su contenido fuera el cuerpo de un script, o como está en forma de una función de shell.
_fn
maneja stdin
- en este caso "arg2" echo
ed sobre |pipe
- en la primera línea ajustando set
su $@
matriz de shell de parámetros posicionales a todo lo que se pasa en la línea de comandos - o "$@"
- Y todo cat
se escupe a través de $(comand substitution)
.
while _fn's $1
El primer parámetro es ${set+}
sustituir el incorporado del shell :true
para satisfacer el while
condicional del bucle. Tan pronto como $1
se descifra que la sustitución no se produce, el condicional se evalúa false
y el while
bucle se rompe.
Para cada iteración del while
bucle, _fn() echo
es su $1
primer parámetro &&
si tiene éxito ( echo
essiempreexitoso) [ tests ]
para ver si $1
es igual a la cadena "arg2"
&&
si el [ test ]
éxito _fn() echo
es $1
nuevamente.
$YOUR_CHK
es una operación nula: es una variable no configurada que no se evalúa como nada antes de que el shell ejecute cualquier código.
Para cada iteración del while
ciclo shift
eliminamos el $1
primer parámetro. Entonces, en la iteración 1 "$@"
se ve así:
arg1 arg2
Pero después de shift
la primera vez se ve así:
arg2
Y después de shift
la última vez se ve así:
Entonces esto nos lleva nuevamente a ${1+:} false
: debido a que $1
ahora no está configurado, el shell no sustituirá :true
y en su lugar solo false
se evaluará, lo que rompe el while
ciclo y finaliza el_fn().