Estoy intentando verificar la cantidad de trabajos de PBS en ejecución y en cola analizando el resultado de qstat -tn1
un bash
script. Hasta ahora, esto ha funcionado:
count ()
{
qstat -tn1 | awk '
BEGIN { R = 0; Q = 0; }
$10 == "R" { R++ }
$10 == "Q" { Q++ }
END { print R, Q }'
}
if read -r R Q < <(count)
...
Sin embargo, veo que qstat
en ocasiones falla por motivos desconocidos. En ese caso, no imprime nada stdout
y algún mensaje de error stderr
y sale con un estado distinto de cero (bastante estándar). Sin embargo, awk
no sabe que qstat
falló y felizmente imprime 0 0
la entrada vacía que recibió. Luego read
asigna 0 a ambos R
y Q
sin saber que qstat
en realidad falló.
- Necesito inicializar
R
yQ
con 0 en elBEGIN
bloque delawk
script, porque puede que no haya procesos en ejecución o procesos en cola, y necesito imprimir0
, no solo una cadena vacía, para la cantidad de dichos procesos. - Podría hacerlo
set -o pipefail
, lo que permitiríacount
salir con un estado distinto de cero, peroread
no puedo ver el estado de salida y, de todos modosawk
, se ejecuta e imprime0 0
para la entrada vacía. - Podría probar una canalización con nombre y subprocesos, pero tener que administrarlos parece una exageración y demasiado complicado.
¿Existe alguna buena manera de permitir que la persona que llama count
detecte su falla?
Respuesta1
Creo que leer count
en una sustitución de proceso le impide obtener su estado de devolución. Entonces no lo hagas. En su lugar, almacene el resultado en una variable o utilice una tubería.
count=$(count)
if [ $? -eq 0 ]; then
read -r R Q <<<"$count"
…
o
set -o pipefail
if count | { read -r R Q; … }
Otra posibilidad es utilizar la PIPESTATUS
variable para comprobar el estado de devolución del primer comando.
count=$(qstat -tn1 | awk …)
if ((${PIPESTATUS[0]} == 0)); then
read P Q
…
Alternativamente, haga arreglos para que awk imprima algo distintivo (por ejemplo, nada) cuando su entrada esté vacía.
awk '
BEGIN { R = 0; Q = 0; }
$10 == "R" { R++ }
$10 == "Q" { Q++ }
END { if (NR) print R, Q }'
Puede probar si la entrada de un comando está vacía con ifne
frommásutilsootros metodos. Pero como estás ingresando a awk, también puedes hacerlo directamente dentro del script awk que ya tienes.
Si necesita obtener el estado de retorno del qstat
comando, puede enviarlo a awk como una línea de entrada adicional. Para facilitar el análisis, haga que la última línea tenga un formato único.
{
qstat -tn1
echo exit_code = $?
} | awk '
…
/^exit_code = / { status = $3 }
END { if (status == 0) print Q, R }
'
Respuesta2
Este:
count ()
{
{ qstat -tn1 || echo "EPIC FAIL" } | awk '
BEGIN { R = 0; Q = 0; }
$10 == "R" { R++ }
$10 == "Q" { Q++ }
END { print R, Q }'
}
if read -r R Q < <(count)
...
Si qstat
tiene éxito, su salida se envía a awk
. Si qstat
devuelve un estado distinto de cero, se envía el texto "EPIC FAIL" awk
.
Este es sólo un ejemplo. Reemplace el eco con algo apropiado que pueda manejar dentro awk
o con if read
.