Estou tentando verificar o número de trabalhos PBS em execução e na fila analisando a saída de qstat -tn1
um bash
script. Até agora, isso funcionou:
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)
...
No entanto, vejo que qstat
ocasionalmente falha por razões desconhecidas. Nesse caso, ele não imprime nada stdout
e alguma mensagem de erro stderr
e sai com um status diferente de zero (bastante padrão). No entanto, awk
não sabe que qstat
falhou e imprime com satisfação 0 0
a entrada vazia que recebeu. Depois read
atribui 0 para ambos R
e Q
sem saber que qstat
realmente falhou.
- Preciso inicializar
R
eQ
com 0 noBEGIN
bloco doawk
script, pois pode não haver processos em execução ou processos na fila, e preciso imprimir0
, não apenas uma string vazia, para o número desses processos. - Eu poderia fazer isso
set -o pipefail
, o que permitiriacount
sair com um status diferente de zero, masread
não consigo ver o status de saída e, de qualquer maneira,awk
é executado e imprime0 0
a entrada vazia. - Eu poderia tentar um pipe nomeado e subprocessos, mas ter que gerenciá-los parece um exagero e muito complicado.
Existe alguma boa maneira de permitir que o chamador count
detecte sua falha?
Responder1
Acho que ler count
uma substituição de processo impede que você obtenha seu status de retorno. Então não faça isso. Em vez disso, armazene o resultado em uma variável ou use um canal.
count=$(count)
if [ $? -eq 0 ]; then
read -r R Q <<<"$count"
…
ou
set -o pipefail
if count | { read -r R Q; … }
Outra possibilidade é utilizar a PIPESTATUS
variável para verificar o status de retorno do primeiro comando.
count=$(qstat -tn1 | awk …)
if ((${PIPESTATUS[0]} == 0)); then
read P Q
…
Alternativamente, faça com que o awk imprima algo distinto (por exemplo, nada) quando sua entrada estiver vazia.
awk '
BEGIN { R = 0; Q = 0; }
$10 == "R" { R++ }
$10 == "Q" { Q++ }
END { if (NR) print R, Q }'
Você pode testar se a entrada de um comando está vazia com ifne
frommaisutilsouOutros métodos. Mas como você está acessando o awk, é melhor fazer isso dentro do script awk que você já possui.
Se você precisar obter o status de retorno do qstat
comando, poderá alimentá-lo no awk como uma linha de entrada extra. Para facilitar a análise, faça com que a última linha tenha um formato exclusivo.
{
qstat -tn1
echo exit_code = $?
} | awk '
…
/^exit_code = / { status = $3 }
END { if (status == 0) print Q, R }
'
Responder2
Esse:
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)
...
Se qstat
for bem-sucedido, sua saída será enviada para awk
. Se qstat
retornar um status diferente de zero, o texto "EPIC FAIL" será enviado para awk
.
Este é apenas um exemplo. Substitua o echo por algo apropriado que você possa manipular dentro awk
ou com if read
.