O bash abre arquivos no O_APPEND ao usar o “” no linux?

37

Se usarmos echo 1234 >> some-file , a Documentação informará que a saída é anexada.

Meu palpite é que, se algum arquivo não existir, o O_CREAT criará um novo arquivo. Se > foi usado, então O_TRUNC truncará o arquivo existente.

No caso de >> : O arquivo será aberto como O_WRONLY (ou O_RDWR) e será finalizado e a operação de gravação será concluída, simulando O_APPEND? Ou será que o arquivo será aberto como O_APPEND, deixando-o ao kernel para garantir que o acréscimo aconteça?

Estou perguntando isso porque um processo de conserver está sobrescrevendo alguns marcadores inseridos pelo echo, quando o arquivo de saída é do ponto de montagem do NFS, & A documentação do NFS diz que O_APPEND não é suportado no servidor, portanto, o kernel do cliente terá que lidar com isso. Eu acho que o processo conserver está usando O_APPEND, mas não tenho certeza do bash >> no linux, portanto, fazendo a pergunta aqui.

    
por Prem 11.05.2015 / 20:28

4 respostas

58

Eu corri isto: strace -o spork.out bash -c "echo 1234 >> some-file" para descobrir sua pergunta. Isso é o que eu encontrei:

open("some-file", O_WRONLY|O_CREAT|O_APPEND, 0666) = 3

Nenhum arquivo chamado "algum arquivo" existia no diretório em que eu executei o comando echo .

    
por 11.05.2015 / 20:47
48

Isso não é feito apenas no Bash, é exigido pelo padrão.

Da única especificação Unix :

Appended output redirection shall cause the file whose name results from the expansion of word to be opened for output on the designated file descriptor. The file is opened as if the open() function as defined in the System Interfaces volume of POSIX.1-2008 was called with the O_APPEND flag. If the file does not exist, it shall be created.

Qualquer shell compatível com POSIX deve fazê-lo. Em alguns sistemas Unix, /bin/sh pode ser um shell Bourne não-POSIX (O shell Bourne foi originalmente escrito antes de O_APPEND ser inventado), e o shell POSIX disponível normalmente será ksh , que estará disponível como sh em um local de caminho diferente, como /usr/xpg4/bin do Solaris.

    
por 11.05.2015 / 22:53
31

Procurando na fonte, ele usa O_APPEND. Para bash 4.3.30 em make_cmd.c line 710-713 leia:

case r_appending_to:                /* >>foo */
case r_append_err_and_out:          /* &>> filename */
  temp->flags = O_APPEND | O_WRONLY | O_CREAT;
  break;
    
por 11.05.2015 / 20:52
19

Vamos investigar isso usando strace em um sistema de arquivos local (não NFS):

$ strace -eopen -- bash -c "echo foo >> /tmp/testfile000" 2>&1 | grep /tmp/testfile000
open("/tmp/testfile000", O_WRONLY|O_CREAT|O_APPEND, 0666) = 3

$ strace -eopen -- bash -c "echo foo > /tmp/testfile000" 2>&1 | grep /tmp/testfile000
open("/tmp/testfile000", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3

Outros shells, a saber, dash , dash , sh do busybox 'e mksh , se comportam da mesma maneira.

A opção -e open significa -e trace=open para rastrear somente a chamada do sistema open() .

    
por 13.05.2015 / 08:55