Scripts de shell conectados com pipe: terminação de trap de um script

1

Eu tenho dois scripts de shell, um é executado em um servidor e grava alguns arquivos em um diretório temporário. Este diretório é então enviado como um arquivo tar para stdout. No final (ou quando é interrompido), o diretório temporário deve ser excluído. O script do servidor (salvo, por exemplo, em '~ / get_dumps.sh') se parece com isto:

#!/bin/sh
set -e
temp_dir='mktemp -d'
cd $temp_dir
trap "rm -r $temp_dir; exit" HUP INT TERM PIPE
for db in db1 db2 db3
  do
    pg_dump $db postgres > $db.sql
done
tar cJf - .
rm -r $temp_dir

O script do servidor é chamado de um cliente com este script:

#!/bin/sh
set -e
temp_dir='mktemp -d'
trap "rm -r $temp_dir; exit" HUP INT TERM PIPE
mkdir /tmp/dumps
ssh server '~/get_dumps.sh' | tar xJf - -C $temp_dir
ls $temp_dir
rm -r $temp_dir

Se eu executar o script do cliente e pressionar Ctrl-C, nem no cliente nem no servidor, os diretórios temporários serão removidos. Por que o trap aqui não funciona?

Editar: primeiro, esqueci de adicionar set -e .

    
por Fabian Heller 19.04.2017 / 05:35

1 resposta

0

O problema foi set -e . Se alguém pressionar, e. Ctrl-c enquanto vários comandos são canalizados juntos, SIGINT não é enviado para o script, mas em outro lugar. Isso cria um erro que é manipulado por set -e e, portanto, o script sai diretamente. Para usar set -e confiável em scripts com pipes, também é necessário interceptar EXIT :

#!/bin/sh
set -e
temp_dir='mktemp -d'
cd $temp_dir
trap "rm -r $temp_dir; exit" HUP INT TERM PIPE EXIT
 for db in db1 db2 db3
   do
     pg_dump $db postgres > $db.sql
done
tar cJf - .

Nesse caso, também o exit normal é tratado pelo trap, que em muitos casos é útil de qualquer maneira.

    
por 28.05.2018 / 10:42