Se eu quiser fazer o conteúdo file2
corresponder ao conteúdo file1
, obviamente poderia simplesmente executar cp file1 file2
.
No entanto, se eu quero preservar tudo sobre file2
exceto o conteúdo-proprietário, permissões, atributos estendidos, ACLs, hard links, etc., etc., então eu não quero correr cp
. * Nesse caso, eu só quero plop o conteúdo de file1
em file2
.
Parece que o seguinte faria:
< file1 > file2
Mas isso não funciona. file2
é truncado para nada e não gravado para. Contudo,
cat < file1 > file2
faz o trabalho.
Surpreendeu-me que a primeira versão não funcione.
A segunda versão é um UUOC? Existe uma maneira de fazer isso sem chamar um comando, apenas usando redirecionamentos?
Nota: Estou ciente de que o UUOC é mais um ponto pedante do que um verdadeiro anti-padrão.
* Como tniles09 descoberto , cp
vontade de fato trabalhar neste caso.
fonte
< file1 > file2
o que você quer depende do shell.<
...file1
não existe ou então é ilegível e você o abre<
antes que a>
saída seja aberta e depois considere o que acontece quando você permitecat
tentar abri-lo.cat
(por padrão), essencialmente executando o segundo comando. Veja a resposta de Stéphane Chazelas abaixo para saber mais sobre o que cabe em um comentário.Respostas:
cat < file1 > file2
não é um UUOC. Classicamente,<
e>
faça redirecionamentos que correspondem a duplicações do descritor de arquivo no nível do sistema. As duplicações do descritor de arquivo, por si só, não fazem nada (bem, os>
redirecionamentos são abertos comO_TRUNC
, para ser preciso, os redirecionamentos de saída truncam o arquivo de saída). Não deixe que os<
>
símbolos o confundam. Os redirecionamentos não movem dados - eles atribuem descritores de arquivo a outros descritores de arquivo.Nesse caso, você abre
file1
e atribui esse descritor de arquivo ao descritor de arquivo0
(<file1
==0<file1
)file2
e atribui esse descritor de arquivo ao descritor de arquivo1
(>file2
==1>file2
).Agora que você tem dois descritores de arquivo, precisa de um processo para extrair dados entre os dois - e
cat
é para isso.fonte
Não é porque, como outros já apontaram, o comportamento em questão depende do shell. Como você (o OP) apontou, isso é um pouco pedante , talvez até engraçado? , tipo de tópico.
No entanto, em sistemas GNU, a sua premissa inicial tem outra solução disponível:
cp --no-preserve=all file1 file2
. Experimente, acho que satisfará a situação descrita (por exemplo, modificar o conteúdofile2
sem modificar seus atributos).Exemplo :
ATUALIZAÇÃO Na verdade, eu só notei que meu sistema
cp
por si só parece preservar atributos, a menos que-a
ou-p
são especificados. Estou usando o bash shell e o GNU coreutils. Eu acho que você aprende algo novo todos os dias ...Resultados do teste (por curinga), incluindo link físico e permissões diferentes:
fonte
No
zsh
shell onde< file1 > file2
funciona, o shell invocacat
.Para uma linha de comando que consiste apenas em redirecionamentos e nenhum comando ou designação,
zsh
chama$NULLCMD
(cat
por padrão), a menos que o único redirecionamento seja<
aquele em que caso$READNULLCMD
(pager
por padrão) é chamado. (a menos quezsh
esteja dentrosh
oucsh
emulação, caso em que se comporta como as conchas que emula).Tão:
é realmente o mesmo que
e
é o mesmo que
fonte
não funciona porque não há comando lá; nenhum processo. O shell abre / cria os arquivos e organiza os redirecionamentos (o que significa que os descritores de arquivos que referenciam esses arquivos são plantados como 0 e 1: entrada padrão e saída padrão). Mas não há nada para executar um loop para ler da entrada padrão e gravar na saída padrão.
zsh
faz esse trabalho substituindo um comando configurável pelo usuário neste caso "comando nulo". O comando não está visível na linha de comando, mas ainda está lá. Um processo é criado para ele e funciona da mesma maneira.NULLCMD
écat
, por padrão, de modo que< from > to
realmente significacat < from > to
emzsh
, a menos queNULLCMD
está definido para algo mais; é um comando "gato implícito".Um "uso inútil de gato" ocorre quando
cat
é usado como intermediário para ler um arquivo e alimentar os dados para outro processo, cujo descritor de arquivo pode ser conectado apenas ao arquivo original.Se
cat
for removível da situação, de modo que os comandos restantes ainda possam executar a mesma tarefa, será inútil. Se não for removível, não será inútil.Um
cat
que é substituível não é a mesma coisa. Por exemplo, em vez decat > file
podemos usarvi file
para criar o arquivo. Isso não conta como remoçãocat
, ao usar o que resta para realizar a mesma tarefa.Se
cat
é o único comando no pipeline, é claro que não pode ser removido; nenhum rearranjo do que sobrar fará o trabalho equivalente.Alguns scripts de shell usam
cat
porque acham que permite mover o operando de entrada para mais perto do lado esquerdo da linha de comando. No entanto, os redirecionamentos podem estar em qualquer lugar na linha de comando:fonte
f -
tar.tar xf -
é justotar x
.cat
está envolvido na criação do arquivo? A resposta diz claramente que o shell faz isso. A que problema> file
você está se referindo? Costumo usá-lo sozinho para truncar um arquivo existente com tamanho zero ou garantir que ele exista. Esta pergunta é sobre por< from > to
que não funciona comocat < from > to
, e UUoC, não "por favor me dê razões pelas quaiscat
não é um bom substituto paracp
".tar
é o arquivador de fitas . Muitastar
implementações ainda funcionam com o primeiro dispositivo de fita por padrão.< file1 > file2
Parece ser dependente do shell, no zsh funciona, no bash não.edit: declaração falsa excluída
fonte
cp -a
preserva os atributos do arquivo1 e substitui os atributos do arquivo2. Oposto ao comportamento desejado. Além disso, não posso dizer, mesmo olhando para a página de manual, o que acontecerá com os links físicos, mas acho seguro dizer que os links físicos do arquivo2 não serão preservados.Além de todas as boas respostas, você pode evitar um UUOC simulando um
cat
:Esses comandos não copiam os metadados do arquivo, como
cp
seria simples .fonte
cat
. Aqui você precisa de um comando para empurrar dados entre os dois descritores de arquivo ecat
é um dos melhores para isso. Veja também opv
que seria capaz de usarsplice()
no Linux por quinos (embora não sejafadvise(POSIX_FADV_SEQUENTIAL)
como o GNUcat
).dd
comando para arquivos binários parece bom ... oucat
funcionaria tão bem quanto para arquivos binários?cat
também funciona para arquivos binários (o Unix geralmente não distingue; no entanto, algumas ferramentas trabalham especificamente linha por linha, como awk, grep, wc, ... uma ferramenta orientada a linhas pode recusar-se a lidar com linhas excessivamente grandes.)sed '' < file1 > file2
;-)Se funcionar, não conserte.
eu usaria
e não suar o PC da semântica.
fonte