Devo usar colchetes de ângulo único ou duplo para redirecionar para / dev / null?

18

A maioria das respostas aqui [ 1 ] [ 2 ] [ 3 ] usa um colchete angular único para redirecionar para / dev / null, assim:

command > /dev/null

Mas anexar a / dev / null também funciona:

command >> /dev/null

Exceto pelo personagem extra, há alguma razão para não fazer isso? Um desses "melhor" é a implementação subjacente de / dev / null?

Edit:
A página de manual open (2) diz que lseek é chamado antes de cada gravação em um arquivo no modo de acréscimo:

O_APPEND
O arquivo é aberto no modo de acréscimo. Antes de cada gravação (2), o deslocamento do arquivo é posicionado no final do arquivo, como se fosse o lseek (2). A modificação do deslocamento do arquivo e a operação de gravação são executadas como uma única etapa atômica.

o que me faz pensar que pode haver uma pequena penalidade no desempenho pelo uso >>. Mas, por outro lado, truncar / dev / null parece uma operação indefinida de acordo com esse documento:

O_TRUNC
Se o arquivo já existe e é um arquivo normal e o modo de acesso permite a gravação (ou seja, é O_RDWR ou O_WRONLY), ele será truncado para o comprimento 0. Se o arquivo for um FIFO ou arquivo de dispositivo terminal, o sinalizador O_TRUNC será ignorado. Caso contrário, o efeito de O_TRUNC não é especificado.

e a especificação POSIX diz >que truncará um arquivo existente , mas O_TRUNC é definido pela implementação para arquivos de dispositivos e não há nenhuma palavra sobre como / dev / null deve responder à truncagem .

Então, truncar / dev / null é realmente não especificado? E as chamadas lseek têm algum impacto no desempenho da gravação?

Morgan
fonte

Respostas:

27

Por definição, /dev/nullafunda qualquer coisa gravada nele ; portanto, não importa se você escreve no modo de acréscimo ou não, tudo é descartado. Como ele não armazena os dados, não há nada a acrescentar.

Então, no final, é apenas mais curto para escrever > /dev/nullcom um >sinal.

Quanto à adição editada:

A página de manual open (2) diz que lseek é chamado antes de cada gravação em um arquivo no modo de acréscimo.

Se você ler atentamente, verá: (grifo meu):

o deslocamento do arquivo é posicionado no final do arquivo, como se com lseek (2)

Ou seja, na verdade (não é necessário) chamar a chamada de lseeksistema, e o efeito também não é estritamente o mesmo: chamar lseek(fd, SEEK_END, 0); write(fd, buf, size);sem O_APPENDnão é o mesmo que escrever no modo de acréscimo, pois com chamadas separadas outro processo pode gravar no entre as chamadas do sistema, descartando os dados anexados. No modo de adição, isso não acontece (exceto no NFS, que não suporta o modo de adição real ).

O texto no padrão não menciona lseeknesse ponto, apenas as gravações devem terminar no final do arquivo.

Então, truncar / dev / null é realmente não especificado?

A julgar pelas escrituras a que você se refere, aparentemente é definido pela implementação. Significando que qualquer implementação sã fará o mesmo que com pipes e TTYs, ou seja, nada. Uma implementação insana pode fazer outra coisa, e talvez truncamento possa significar algo sensato no caso de algum outro arquivo de dispositivo.

E as chamadas lseek têm algum impacto no desempenho da gravação?

Teste-o. É a única maneira de saber com certeza em um determinado sistema. Ou leia a fonte para ver onde o modo de acréscimo altera o comportamento, se houver.

ilkkachu
fonte
-3

Se você deseja eficiência, use-o command >&-. Isso fecha o descritor de arquivos em vez de redirecioná-lo, para que não seja desperdiçado tempo escrevendo coisas nele.

db48x
fonte
3
Não feche fluxos com menos de 3. Isso aliases os descritores std * com descritores aleatórios de arquivos; potencialmente com resultados catastróficos.
Joshua
7
Se você apenas fechar o descritor de arquivo, o programa receberá erros em todas as chamadas de gravação, provavelmente causando mensagens de erro irritantes e possivelmente o programa sendo encerrado antes de concluir sua tarefa.
ilkkachu