Como o 'arquivo do cat' funciona?

39

cat < file imprime o conteúdo do arquivo para stdout.

cat > file lê stdin até que + D seja detectado e o texto de entrada seja gravado em arquivo .

cat <> file , pelo menos na minha versão do Bash, imprime o conteúdo de arquivo de forma feliz (sem erro), mas não modifica o arquivo nem atualiza o registro de data e hora da modificação.

Como o padrão Bash justifica o > aparentemente ignorado na terceira declaração - e, mais importante, está fazendo qualquer coisa?

    
por Qix 27.10.2014 / 06:30

2 respostas

44

O Bash usa <> para criar um descritor de arquivos de leitura / gravação :

The redirection operator

[n]<>word

causes the file whose name is the expansion of word to be opened for both reading and writing on file descriptor n, or on file descriptor 0 if n is not specified. If the file does not exist, it is created.

cat <> file abre file leitura-gravação e liga-o ao descritor 0 (entrada padrão). É essencialmente equivalente a < file para qualquer programa escrito de maneira sensata, já que é improvável que alguém tente escrever normalmente a entrada padrão, mas, se conseguir, poderá fazê-lo.

Você pode escrever um programa C simples para testar isso diretamente - write(0, "hello", 6) irá escrever hello em file via entrada padrão.

<> deve também funcionar em qualquer outro shell compatível com POSIX com o mesmo efeito.

    
por 27.10.2014 / 06:44
32

<> file abre o arquivo (por padrão, no descritor de arquivo 0 (stdin), como < ) no modo leitura + gravação sem truncamento e criando o arquivo se ele não existia anteriormente .

Isso corresponde aos O_RDWR|O_CREAT sinalizadores passados para a chamada de sistema open() . Por contraste, < é O_RDONLY e > é O_WRONLY|O_CREAT|O_TRUNC e >> O_WRONLY|O_CREAT|O_APPEND .

Ter stdin gravável não costuma ser útil, pois os aplicativos geralmente não gravam em seu stdin. Os aplicativos geralmente não esperam ler e escrever em um descritor de arquivo que recebem na inicialização; eles geralmente lêem de stdin (ou um descritor de arquivo que eles mesmos abrem) e escrevem para stdout ou stderr (ou um descritor de arquivo que eles mesmos abrem).

<> pode ter seus usos:

  • Você pode preferir cat <> file over cat < file se não quiser que o comando falhe se file não existir, mas um file vazio foi criado em seu lugar.
  • O aspecto sem truncar de <> torna útil substituir os arquivos no lugar. Nesse caso, no entanto, você geralmente não o usa no descritor de arquivo 0:

    printf xxx 1<> file
    

    substitui os primeiros 3 bytes de file por xxx .

  • Em alguns sistemas como o Linux, <> em um pipe nomeado (FIFO) abre o pipe nomeado sem bloquear (sem esperar que algum outro processo abra a outra extremidade) e garante que a estrutura do pipe permaneça ativa. Por exemplo em:

    mkfifo pipe; sed 's/foo/bar/g' <> pipe
    

    sed manipula dados recebidos de qualquer número de outros processos gravados nele e nunca vê eof .

por 27.10.2014 / 13:35