Respostas:
cat /dev/null > file.txté um uso inútil de gato .
Basicamente, cat /dev/nullsimplesmente resulta em catnada de saída. Sim, funciona, mas é desaprovado por muitos porque resulta na invocação de um processo externo que não é necessário.
É uma daquelas coisas comuns simplesmente porque é comum.
Usar apenas > file.txtfuncionará na maioria dos shells, mas não é totalmente portátil. Se você quiser totalmente portátil, a seguir estão boas alternativas:
true > file.txt
: > file.txt
Ambos :e truenão produzem dados, e são componentes internos do shell (embora catseja um utilitário externo), portanto, são mais leves e mais 'adequados'.
Atualizar:
Como Tylerl mencionou em seu comentário, também há a >| file.txtsintaxe.
A maioria dos shells possui uma configuração que os impede de truncar um arquivo existente via >. Você deve usar em seu >|lugar. Isso é para evitar erros humanos quando você realmente deseja anexar >>. Você pode ativar o comportamento com set -C.
Portanto, com isso, acho que o método mais simples, adequado e portátil de truncar um arquivo seria:
:>| file.txt
:também é mandatado pelo POSIX para ser embutido e, na verdade, é diferente do truefato de ser considerado um embutido "especial" .
>| fileé um truncado mais explícito.
trueé necessário que ele seja construído e tradicionalmente não era. :é construído em todas as conchas da família Bourne. :é um built-in especial por POSIX (portanto : > file, sairá do shell, por exemplo, se filenão puder ser aberto para escrever em shells POSIX) e truenão será. O POSIX até menciona que :pode ser mais eficiente do que trueem alguns sistemas.
Bourne POSIX zsh csh/tcsh rc/es fish
> file Y Y N(1) N(1) N N
: > file N/Y(2) Y(3) Y Y(4) N(5) N(5)
true > file Y(5) Y Y Y(5) Y(5) Y(5)
cat /dev/null > file Y(5) Y Y(5) Y(5) Y(5) Y(5)
eval > file Y(3,8) Y(3) Y Y(6) Y Y
cp /dev/null file (7) Y(5) Y Y(5) Y(5) Y(5) Y(5)
printf '' > file Y(5) Y Y Y(5) Y(5) Y
Notas:
shou kshemulation, para redirecionamentos sem um comando, no zsh, um comando padrão é assumido (um pager apenas para o redirecionamento stdin, catcaso contrário), que pode ser ajustado com as variáveis NULLCMD e READNULLCMD. Isso é inspirado no recurso semelhante em(t)csh:no UnixV7, pois :foram interpretados a meio caminho entre um líder de comentário e um comando nulo. Mais tarde, eles foram e foram para todos os componentes internos, se o redirecionamento falhar, que sai do shell.:e evalsendo built-ins especiais, se o redirecionamento falhar, que sai do shell ( bashsomente isso no modo POSIX).(t)csh, isso está definindo um rótulo nulo (para goto), para que goto ''haja ramificação lá. Se o redirecionamento falhar, isso sai do shell.$PATH( :geralmente não é; true, cat, cpe printfgeralmente são (POSIX exige que eles)).fileNo entanto, se houver um link simbólico para um arquivo inexistente, algumas cpimplementações como o GNU se recusarão a criá-lo.(esta seção é altamente subjetiva)
> file. Isso >parece muito com um prompt ou um comentário. Além disso, a pergunta que vou fazer ao ler isso (e a maioria das conchas se queixam da mesma) é qual saída exatamente você está redirecionando? .: > file. :é conhecido como o comando no-op. Então, isso é lido imediatamente como gerando um arquivo vazio. No entanto, aqui novamente, isso :pode ser facilmente esquecido e / ou visto como um prompt.true > file: o que booleano tem a ver com o redirecionamento ou o conteúdo do arquivo? O que se entende aqui? é a primeira coisa que me vem à cabeça quando leio isso.cat /dev/null > file. Concatenar /dev/nullem file? catsendo muitas vezes visto como o comando para despejar o conteúdo do arquivo, que ainda pode fazer sentido: despejar o conteúdo do arquivo vazio emfile , um pouco como um modo complicado de dizer cp /dev/null file, mas ainda compreensível.cp /dev/null file. Copia o conteúdo do arquivo vazio para file. Faz sentido, embora alguém que não saiba como cpdeve ser feito por padrão possa pensar que você está tentando criar fileum nulldispositivo também.eval > fileou eval '' > file. Não executa nada e redireciona sua saída para a file. Faz sentido para mim. Estranho que não seja um idioma comum.printf '' > file: explicitamente imprime nada em um arquivo. Aquele que faz mais sentido para mim.A diferença será se estamos usando um shell embutido ou não. Caso contrário, um processo deve ser bifurcado, o comando carregado e executado.
evalé garantido para ser construído em todas as conchas. :está embutido onde quer que esteja disponível (como Bourne / csh). trueestá embutido apenas em conchas semelhantes a Bourne.
printfé embutido na maioria dos modernos cascos Bourne-like e fish.
cpe catgeralmente não são integrados.
Agora cp /dev/null filenão invoca redirecionamentos de shell, portanto, coisas como:
find . -exec cp /dev/null {} \;
serão mais eficientes do que:
find . -exec sh -c '> "$1"' sh {} \;
(embora não necessariamente que:
find . -exec sh -c 'for f do : > "$f"; done' sh {} +
)
Pessoalmente, eu uso : > fileem conchas do tipo Bourne e não uso nada além de conchas do tipo Bourne atualmente.
dd of=file count=0?
dd(como pelo menos Solaris 10), count=0é ignorado. dd if=/dev/null of=fileseria mais portátil. De qualquer forma, isso é independente do shell.
cp /dev/null file, certo?
cp /dev/null fileé um idioma comum. Estou limitando a eles, o ponto não é listar todas as maneiras possíveis.
Você pode querer olhar truncate, o que faz exatamente isso: truncar um arquivo.
Por exemplo:
truncate --size 0 file.txt
Provavelmente é mais lento do que usar true > file.txt.
Meu ponto principal, no entanto, é: truncatedestina-se a truncar arquivos, enquanto o uso de> tem o efeito colateral de truncar um arquivo.
truncateestaria disponível, mas >nem as unistdbibliotecas C estariam disponíveis?
truncateé um utilitário FreeBSD, adicionado relativamente recentemente (2008) aos coreutils do GNU (embora o --sizeestilo de opção longa do GNU seja específico do GNU), portanto não está disponível em sistemas que não são do GNU ou FreeBSD e não está disponível nos sistemas GNU mais antigos, Eu não diria que é portátil. cp /dev/null filefuncionaria sem um redirecionamento de shell e seria mais portátil.
A resposta depende um pouco do que file.txté e como o processo é gravado nela!
Vou citar um caso de uso comum: você tem um arquivo de log crescente chamado file.txte deseja alterná-lo.
Portanto, você copia, por exemplo, file.txtpara e file.txt.save, em seguida, trunca file.txt.
Nesse cenário, se o arquivo não for aberto por another_process(ex: another_processpoderia ser um programa que gera esse arquivo, por exemplo, um programa que registra algo), suas duas propostas são equivalentes e ambas funcionam bem (mas a segunda é preferida como a O primeiro "cat / dev / null> file.txt" é um uso inútil do gato e também abre e lê / dev / null).
Mas o verdadeiro problema seria se o other_processainda estiver ativo e ainda tiver um identificador aberto indo para o arquivo.txt.
Em seguida, surgem 2 casos principais, dependendo de como other processo arquivo foi aberto:
Se o other_processabrir da maneira normal, o identificador ainda estará apontando para o local anterior no arquivo, por exemplo, com deslocamento de 1200 bytes. A próxima gravação começará, portanto, no deslocamento 1200 e, portanto, você terá novamente um arquivo de 1200 bytes (+ o que outro processo escreveu), com 1200 caracteres nulos iniciais! Não é o que você quer , eu presumo.
Se other_processaberto file.txtno "modo de acréscimo", toda vez que ele gravar, o ponteiro procurará ativamente o final do arquivo. Portanto, quando você o truncar, ele "procurará" até o byte 0 e você não terá o efeito colateral ruim! É isso que você quer (... geralmente!)
Observe que isso significa que, ao truncar um arquivo, é necessário garantir que todos os que other_processainda estão gravando no local o tenham aberto no modo "anexar". Caso contrário, será necessário pará-los other_processe iniciá-los novamente, para que eles comecem a apontar para o início do arquivo e não para o local anterior.
Referências: /programming//a/16720582/1841533 para obter uma explicação mais limpa e um bom exemplo curto de diferença entre os logs de modo normal e de acréscimo em /programming//a/984761/1841533
cat /dev/null > filee a > fileé a cat /dev/nulle isso não faz diferença para o arquivo.
Gosto disso e uso-o com frequência porque parece mais limpo e não como se alguém tivesse pressionado a tecla Return por acidente:
echo -n "" > file.txt
Também deve ser um built-in?
echoimplementações não suportam -n(e geraria -n<SPC><NL>aqui. printf '' > file.txtSeria mais portátil (pelo menos entre os sistemas modernos / POSIX).