Respostas:
cat /dev/null > file.txt
é um uso inútil de gato .
Basicamente, cat /dev/null
simplesmente resulta em cat
nada 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.txt
funcionará 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 true
não produzem dados, e são componentes internos do shell (embora cat
seja 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.txt
sintaxe.
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 true
fato 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 file
não puder ser aberto para escrever em shells POSIX) e true
não será. O POSIX até menciona que :
pode ser mais eficiente do que true
em 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:
sh
ou ksh
emulation, para redirecionamentos sem um comando, no zsh, um comando padrão é assumido (um pager apenas para o redirecionamento stdin, cat
caso 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 eval
sendo built-ins especiais, se o redirecionamento falhar, que sai do shell ( bash
somente 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
, cp
e printf
geralmente são (POSIX exige que eles)).file
No entanto, se houver um link simbólico para um arquivo inexistente, algumas cp
implementaçõ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/null
em file
? cat
sendo 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 cp
deve ser feito por padrão possa pensar que você está tentando criar file
um null
dispositivo também.eval > file
ou 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). true
está embutido apenas em conchas semelhantes a Bourne.
printf
é embutido na maioria dos modernos cascos Bourne-like e fish
.
cp
e cat
geralmente não são integrados.
Agora cp /dev/null file
nã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 : > file
em 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=file
seria 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, é: truncate
destina-se a truncar arquivos, enquanto o uso de> tem o efeito colateral de truncar um arquivo.
truncate
estaria disponível, mas >
nem as unistd
bibliotecas C estariam disponíveis?
truncate
é um utilitário FreeBSD, adicionado relativamente recentemente (2008) aos coreutils do GNU (embora o --size
estilo 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 file
funcionaria 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.txt
e deseja alterná-lo.
Portanto, você copia, por exemplo, file.txt
para e file.txt.save
, em seguida, trunca file.txt
.
Nesse cenário, se o arquivo não for aberto por another_process
(ex: another_process
poderia 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_process
ainda estiver ativo e ainda tiver um identificador aberto indo para o arquivo.txt.
Em seguida, surgem 2 casos principais, dependendo de como other process
o arquivo foi aberto:
Se o other_process
abrir 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_process
aberto file.txt
no "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_process
ainda estão gravando no local o tenham aberto no modo "anexar". Caso contrário, será necessário pará-los other_process
e 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 > file
e a > file
é a cat /dev/null
e 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?
echo
implementações não suportam -n
(e geraria -n<SPC><NL>
aqui. printf '' > file.txt
Seria mais portátil (pelo menos entre os sistemas modernos / POSIX).