Shell Script mktemp, qual é o melhor método para criar pipe nomeado temporário?

29

Estou ciente de que é melhor criar arquivos temporários com mktemp , mas e os pipes nomeados?

Eu tenho uma ideia, tenho certeza de que funcionaria, mas eu realmente gostaria de uma opinião de especialistas.

Eu prefiro que as coisas sejam compatíveis com POSIX, mas o Linux só é aceitável. Evitar Bashisms é meu único critério difícil, como eu escrevo em dash .

    
por J. M. Becker 24.01.2012 / 07:25

5 respostas

38
tmppipe=$(mktemp -u)
mkfifo -m 600 "$tmppipe"

Ao contrário da criação de arquivos regulares, que é propensa a ser sequestrada por um arquivo existente ou por um link simbólico, a criação de um canal de nome por meio de mkfifo ou a função subjacente cria um novo arquivo no local especificado ou falha. Algo como : >foo não é seguro, porque se o invasor puder prever a saída de mktemp , o invasor poderá criar o arquivo de destino para si mesmo. Mas mkfifo foo falharia em tal cenário.

Se você precisar de portabilidade POSIX completa, mkfifo -m 600 /tmp/myfifo é seguro contra seqüestro, mas propenso a negação de serviço; sem acesso a um gerador de nome de arquivo aleatório strong, você precisaria gerenciar tentativas de repetição.

Se você não se importa com os sutis problemas de segurança em torno de arquivos temporários, siga uma regra simples: crie um diretório privado e mantenha tudo lá.

tmpdir=
cleanup () {
  if [ -n "$tmpdir" ] ; then rm -rf "$tmpdir"; fi
  if [ -n "$1" ]; then kill -$1 $$; fi
}
tmpdir=$(mktemp -d)
trap 'cleanup' EXIT
trap 'cleanup HUP' HUP
trap 'cleanup TERM' TERM
trap 'cleanup INT' INT
mkfifo "$tmpdir/pipe"
    
por 24.01.2012 / 18:40
4

Uma alternativa mais segura é usar mktemp para criar um diretório com segurança, depois colocar seu named pipe dentro desse diretório, fazer um rm -R $dir para se livrar dele no final.

    
por 07.12.2012 / 08:52
2

Use a opção "execução a seco":

mkfifo $(mktemp -ut pipe.XXX)
    
por 24.01.2012 / 10:55
1

Você pode usar mktemp para criar um arquivo temporário, excluí-lo e criar um canal nomeado com o mesmo nome.

Por exemplo:

TMPPIPE=$(mktemp -t pipe.XXX) && {
    rm -f $TMPPIPE
    mkfifo $TMPPIPE
}
    
por 24.01.2012 / 09:54
0

Use mkfifo ou mknod no Unix, onde dois processos separados podem acessar o canal pelo nome - um processo pode abri-lo como leitor e o outro como um escritor.

mkfifo my_pipe
gzip -9 -c < my_pipe > out.gz
cat file > my_pipe

O pipe nomeado pode ser excluído como qualquer arquivo:

rm my_pipe

mkfifo --mode=0666 /tmp/namedPipe
gzip --stdout -d file.gz > /tmp/namedPipe

O NamedPipe pode ser usado como um arquivo comum apenas para leitura uma vez.

link

    
por 24.01.2012 / 08:08