Suprimir a mensagem GPG "Reading passphrase from file descriptor 0"

2

Simplesmente, como posso fazer com que o GPG não imprima essa mensagem? Aqui estão os comandos que estou usando:

echo "test input" > test.in
echo "test" | gpg -q -c --passphrase-fd 0 --output test.enc --yes --force-mdc test.in
echo "test" | gpg -q -d --passphrase-fd 0 test.enc > test.out

e executá-lo:

$ echo "test input" > test.in 
$ echo "test" | gpg -q -c --passphrase-fd 0 --output test.enc --yes --force-mdc test.in
Reading passphrase from file descriptor 0    
$ echo "test" | gpg -q -d --passphrase-fd 0 test.enc > test.out
Reading passphrase from file descriptor 0

EDITAR: Redirecionar stderr parece não funcionar

$ echo "test" | gpg -q -c --passphrase-fd 0 --output test.enc --yes --force-mdc test.in 2> /dev/null
Reading passphrase from file descriptor 0    
    
por Paul Tarjan 03.01.2010 / 13:47

3 respostas

8

Uma maneira de ver o que está acontecendo é rastrear as chamadas do sistema envolvidas. Utilitários para fazer isso variam de acordo com a plataforma. No Solaris, você usaria treliça . No Linux (como no meu exemplo) você usaria strace .

Para rastrear, alteramos o comando usado de:

echo "test" | gpg -q -c --passphrase-fd 0 --output test.enc --yes --force-mdc test.in 2> /dev/null

para:

echo "test" | strace gpg -q -c --passphrase-fd 0 --output test.enc --yes --force-mdc test.in 2>trace_output.txt .

A primeira coisa que se destaca como interessante (se um pouco não relacionada) é que o gpg está fazendo leituras repetidas de byte único ao tomar a senha de entrada do stdin. Às vezes, isso é um sinal revelador de código ineficiente - mas, nesse caso, provavelmente não é um grande negócio:

read(0, "t", 1)                         = 1
read(0, "e", 1)                         = 1
read(0, "s", 1)                         = 1
read(0, "t", 1)                         = 1
read(0, "\n", 1)                        = 1

As coisas mais relevantes sobre a saída da mensagem de log estão todas aqui:

open("/dev/tty", O_RDWR)                = 3
fstat(3, {st_mode=S_IFCHR|0666, st_rdev=makedev(5, 0), ...}) = 0
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B9600 opost isig icanon echo ...}) = 0
write(3, "Reading passphrase from file des"..., 45) = 45
write(3, "   \n", 7)           = 7

É tudo o que ouvimos sobre o descritor de arquivos 3 até sair (não está explicitamente fechado).

Olhando cada um deles por sua vez:

  • open("/dev/tty", O_RDWR) = 3

    Isso está abrindo o arquivo / dev / tty, tanto para leitura quanto para escrita. O valor de retorno (um novo descritor de arquivo para uso posterior) é 3.

    / dev / tty é um sinônimo para o atual terminal de controle . Você pode ver o dispositivo que está sendo efetivamente referenciado por este arquivo especial, executando $ tty

  • fstat(3, {st_mode=S_IFCHR|0666, st_rdev=makedev(5, 0), ...}) = 0

    Isto é usado pelo gpg para descobrir sobre o arquivo que acabou de abrir com o descritor de arquivo 3. O material entre chaves é o que é retornado (um stat de estrutura preenchido, com o 5, 0 indicando que este é um arquivo especialmente especial ).

  • ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B9600 opost isig icanon echo ...}) = 0

    Isto está manipulando atributos do terminal de controle, antes da saída.

  • write(3, "Reading passphrase from file des"..., 45) = 45

    write(3, " \n", 7) = 7

    Estes são mais diretos. O gpg escreve com sucesso esse texto (parte do qual foi abreviado na saída strace) para o terminal.

Então - esta é sua resposta. gpg está escrevendo esta mensagem de log diretamente para / dev / tty (sinônimo para o terminal de controle), então você não será capaz de redirecioná-la da mesma maneira para stdout ou stderr.

Existe uma maneira de contornar isso. Você pode desconectar o terminal de controle antes de executar o gpg.

Aqui está um pequeno programa que faz exatamente isso:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

int main(int argc, char* argv[])
{
  int rc, fd;
  if (argc != 2)
  {
    fprintf(stderr, 
     "Provide command line arg to execute after TIOCNOTTY\n");
    return EXIT_FAILURE;
  }
  fd = open("/dev/tty", O_RDWR);
  if (fd < 0)
  {
    fprintf(stderr, 
     "Failed to open controlling terminal: %s\n",
     strerror(errno));
    return EXIT_FAILURE;
  }
  rc = ioctl(fd, TIOCNOTTY);
  if (rc == -1)
  {
    fprintf(stderr,
     "Failed TIOCNOTTY ioctrl: %s\b",
     strerror(errno));
    return EXIT_FAILURE;
  }
  return system(argv[1]);
}

Deveria haver um utilitário existente para fazer o acima, mas não consegui encontrar um.

Se você fosse compilar esse código, chame o executável resultante notty , então você poderia fazer isso:

echo "test" | notty "gpg -q -c --passphrase-fd 0 --output test.enc --yes --force-mdc test.in"

Isso deve suprimir a mensagem, mas mantenha seu stdout e stderr intactos. Não está claro o que mais seria suprimido (você precisaria olhar para a fonte gpg para ver o que mais é produzido dessa maneira).

    
por 04.01.2010 / 00:13
7

--batch é a resposta, mas não tenho ideia de como ela está saindo mesmo quando o stderr é redirecionado ...

    
por 03.01.2010 / 21:22
4

Enquanto a resposta do user30579 é útil para entender o problema, vamos reduzi-lo ao mínimo necessário para realmente corrigir o problema:

Use apenas o switch --no-tty incorporado no GPG. por exemplo:

echo "test" | gpg --no-tty -q -c --passphrase-fd 0 --output test.enc --yes --force-mdc test.in
    
por 26.03.2012 / 20:59