Suponha que eu queira canalizar a saída de algum comando para um arquivo. Existe alguma diferença, por menor que seja ou com nuances, entre simplesmente... bem, canalizá-lo para um arquivo como
some-command > file
e canalizá-lo através dd
de como
some-command | dd $MAYBE_SOME_OPTIONS_LIKE_BS of=file
Esta pergunta é principalmente para satisfazer minha curiosidade e, a menos que a última forma tenha algum benefício ou caso de uso não desprezível, na prática, eu pouparia meus dedos do exercício e optaria pela primeira.
Acesso direto a
file
No primeiro caso
some-command
, ele grava emfile
, portanto, pode recuperar metadados (como mtime ou size) por qualquer motivo. Esses metadados têm um significado útil para arquivos comuns, mas para um canal sem nome, eles não têm sentido.some-command
pode até estar interessado em abrir o que seu stdout aponta para leitura, o que é bastante seguro para arquivos comuns e obviamente não é a coisa certa a fazer em seu segundo caso.Mas esses cenários são bastante raros, eu acho.
Buscáveis vs não pesquisáveis
O comportamento de
some-command
pode depender se seu stdout é pesquisável ou não. Geralmente não é o caso, embora seja possível. Um arquivo regular é pesquisável (você pode ler/gravar em qualquer local). Um tubo não é pesquisável.dd
em si é um exemplo válido. Consideresome-command
serdd if=/dev/zero bs=1 count=1 seek=1
. Seus dois exemplos se tornam:O primeiro comando funcionará, sairá
file
com dois bytes nulos. No segundo comando o primeirodd
reclamará que não pode buscar, sairá; o segundodd
não receberá nada, não escreverá nada e sairá sem erro.Eu admito que
seek
isso não é exatamente simples "enviar a saída de algum comando para um arquivo". Mas, em geral,some-command
pode detectar se seu stdout é pesquisável e, em seguida, transmitir uma saída diferente sem realmente procurar. Esta função shell meio que faz isso como uma prova de conceito:Experimente estes e examine o arquivo após cada um:
Sabendo de tudo o que foi dito acima, há um cenário no qual eu consideraria seu segundo comando: if
some-command
de fato se comporta de maneira diferente em dois casos (como nossais-seekable
função) e quero "pensar" que está gravando em um canal, mas quero a saída em um arquivo . Então sim. Embora eu prefira usarcat
em vez dedd
(provavelmente não importaria). Por exemplo, posso querer obter e gravar em um arquivonon-seekable
:is-seekable
Mas só se fizer alguma diferença. Caso contrário, seria o (in)famoso "uso inútil de
cat
". Ou no seu caso "uso inútil dedd
"; ou mesmo "uso nocivo" se você lidar mal com o status de saída.status de saída
Agora tente estes dois exemplos:
Se você verificar
$?
após o segundo, descobrirá que é0
(a menos quedd
falhe). Seu segundo caso descarta o status de saídasome-command
(geralmente; por exemplo, em Bash investigueset -o pipefail
, que não é portátil).Portanto, no segundo caso,
some-command
pode falhar por qualquer motivo e você (ou melhor, a lógica do seu script) não saberá. Isso é suficiente para evitar tubulação desnecessáriadd
(ou tubulação desnecessária).Permissões
Outra nuance:
some-command > file
faz com que o (sub)shell abra o arquivo antes desome-command
ser gerado (executado para);dd of=file
abre o arquivo em seu próprio nome.Existem maneiras de conceder mais direitos de acesso do
dd
que a qualquer outro comando "regular". Em outras palavras, existem maneiras de fazer com que o simplesdd
se comporte mais comosudo dd
sem senha. Você não deveria fazer isso e espero que ninguém faça, mas é possível.O que você pode fazer é conceder direitos de acesso sob demanda:
sudo dd
. Pode ser útil ao tentar gravar em um arquivo restrito. Analise isso:Acho que isso está muito próximo de "benefício ou caso de uso não negligenciável".
Talvez algumas opções
Obviamente
$MAYBE_SOME_OPTIONS_LIKE_BS
pode alterar odd
comportamento. Entendo que opções comoconv=swab
estão fora do escopo porque você desejafile
receber os mesmos dados em ambos os casos.Ainda assim, existem poucas opções que podem fazer a diferença. Exemplos:
status=progress
imprimirá a taxa de transferência e as estatísticas de volume no stderr, ao processar cada bloco de entrada;oflag=noatime
não atualizará o registro de data e hora de acesso do arquivo;oflag=nolinks
falhará se o arquivo tiver vários links físicos;e muito mais .
Os exemplos acima são extensões GNU, não portáteis. Portátil
dd
é caracterizado aqui .BEIJO
Finalmente, há o princípio do KISS : mantenha a simplicidade estúpida. Seu primeiro caso é estúpido e simples.
Nenhum usuário deve notar nenhuma diferença. Do ponto de vista do desempenho, duvido que haja diferença também. Se você pensar em ambos os cenários, há prós e contras, mas eles dependem muito do que você está tentando realizar.
Por exemplo: arquivo cat | dd de=arquivo2 vs arquivo cat > arquivo2. A diferença aqui é que cat abrirá um arquivo, dd herdará o fluxo, a menos que você especifique um tamanho de bloco ou algum tipo de sinalizador de gravação, ele começará a gravar na pilha fs imediatamente.
Se você não usar nenhum recurso do dd, estará apenas bifurcando um intermediário, adicionando um processo, suponho que essa bifurcação dupla teria uma perda mínima de desempenho versus apenas deixar o dd lidar com if=file of=newfile. A vantagem, nesse caso, é que você pode buscar/pular em dd e bom, só tem um processo.
Se você quer dizer estritamente apenas redirecionamento de arquivo versus dd, eu diria que não há diferença se você não fornecer dd com nenhum sinalizador/parâmetro. Você poderia usar neste caso como um buffer intermediário, mas existem alternativas muito melhores, por exemplo: arquivo cat | tampão | gzip > conteúdo gzipado. Por exemplo, a chamada empilhada acima, digamos que você tenha uma origem super rápida e um destino lento, com o buffer no meio, você pode garantir que o lado receptor sempre tenha uma fila de entrada ocupada e, se estiver compactando, pode certifique-se de evitar que sua CPU espere por IO.
Novamente, todos os casos extremos exigiriam perguntas separadas, mas como você vê, se falarmos estritamente de um contra o outro, mesmo que houvesse uma diferença, duvido que seria perceptível, exceto em casos extremos.
Espero que isso ajude, essa pergunta foi bastante interessante, devo dizer, demorei um pouco para pensar sobre isso.