Se um dos programas no pipeline sair, os programas à esquerda também serão encerrados. A maneira como isso funciona é:
- Em
foo | bar
, bar
sai.
- A saída do processo fecha a extremidade de leitura do canal.
- Quando
foo
tenta gravar no pipe, ele recebe um sinal SIGPIPE.
-
foo
morre.
Isso pressupõe que foo
não tenha protegido contra o SIGPIPE; programas podem fazer isso, mas programas típicos de linha de comando não.
Como você deseja apenas uma correspondência, faça o awk sair assim que encontrar a linha em que está interessado:
tar tzf "archive.tar.gz" | awk -F/ '$NF ~ /.my-file-name\.ext$/ {print $NF; exit}'
ou (não é realmente vantajoso aqui)
tar tzf "archive.tar.gz" | sed -n '/[^/]my-file-name\.ext$/ {s!.*/!!; q}'
ou, continuando com sua abordagem mais complicada de usar o grep separadamente do awk
tar tzf "archive.tar.gz" | awk -F/ '{ if($NF != "") print $NF }' | grep -e "^..*my-file-name\.ext$" | head -n 1
Sair do leitor faz com que tar
seja encerrado quando ele for gravado no canal, o que pode demorar um pouco, devido a buffer de saída . (Levará um tempo especialmente longo se houver mais de dois processos no pipe, pois haverá algum atraso para cada um receber SIGPIPE.) Depois que awk
sair, find
gastará um pouco lendo o arquivo e preenchendo o próximo buffer com os nomes dos arquivos, e finalmente tente gravar o buffer e morrer com o SIGPIPE. Para este aplicativo, é muito provável que seja mais rápido alternar o tar para o buffer de linha para saída, o que você pode fazer com stdbuf
:
stdbuf -oL tar tzf "archive.tar.gz" | awk -F/ '$NF ~ /.my-file-name\.ext$/ {print $NF; exit}'
Alternativamente, você pode organizar o kill do programa tar quando o awk sair, mas isso é mais complicado.
sh -m 'tar tzf "archive.tar.gz" | {
awk -F/ "$0";
kill -TERM -$$;
}' '$NF ~ /.my-file-name\.ext$/ {print $NF; exit}'
[ $? -eq 143 ]