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 dotrue
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, sefile
não puder ser aberto para escrever em shells POSIX) etrue
não será. O POSIX até menciona que:
pode ser mais eficiente do quetrue
em alguns sistemas.Em termos de portabilidade:
Notas:
sh
ouksh
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.:
eeval
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 (paragoto
), para quegoto ''
haja ramificação lá. Se o redirecionamento falhar, isso sai do shell.$PATH
(:
geralmente não é;true
,cat
,cp
eprintf
geralmente são (POSIX exige que eles)).file
No entanto, se houver um link simbólico para um arquivo inexistente, algumascp
implementações como o GNU se recusarão a criá-lo.Em termos de legibilidade:
(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
emfile
?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 dizercp /dev/null file
, mas ainda compreensível.cp /dev/null file
. Copia o conteúdo do arquivo vazio parafile
. Faz sentido, embora alguém que não saiba comocp
deve ser feito por padrão possa pensar que você está tentando criarfile
umnull
dispositivo também.eval > file
oueval '' > file
. Não executa nada e redireciona sua saída para afile
. 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.Em termos de desempenho
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 efish
.cp
ecat
geralmente não são integrados.Agora
cp /dev/null file
não invoca redirecionamentos de shell, portanto, coisas como:serão mais eficientes do que:
(embora não necessariamente que:
)
Pessoalmente
Pessoalmente, eu uso
: > file
em conchas do tipo Bourne e não uso nada além de conchas do tipo Bourne atualmente.fonte
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:
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.fonte
truncate
estaria disponível, mas>
nem asunistd
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 efile.txt.save
, em seguida, truncafile.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
abertofile.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á-losother_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
fonte
cat /dev/null > file
e a> file
é acat /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:
Também deve ser um built-in?
fonte
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).