Esta não é uma pergunta "como anexar e não substituir". Não estou procurando um arquivo que combine a saída de dois comandos. É apenas um erro que cometi e gostaria de entender por que o sistema fez o que fez
Eu uso um comando (em uma linha de comando ssh remota) que leva muito tempo para ser concluído e gera dados (linha por linha a cada poucos segundos) para stdout, então redireciono para um arquivo:
command > file.out &
Às vezes, a sessão remota é desconectada, mas o comando continua sendo executado em segundo plano. Eu não sabia disso, então executo o mesmo comando novamente, antes que o primeiro tenha terminado :
command > file.out &
Quando ambos os processos terminarem, eu esperaria ter (depois de ler algumas respostas neste site) um único arquivo com as linhas de ambos os comandos bagunçadas, mas o arquivo de saída só tem a saída de uma das 2 execuções.
Por que o arquivo não tem as duas saídas entrelaçadas (como avisado nos comentários aqui )? A qual das 2 saídas pertence o arquivo final?
EDITAR:
Removida uma das perguntas (por que o arquivo de saída não está bloqueado para gravação?) conforme explicado aqui
Quando você abre um arquivo para escrita usando o
>
redirecionamento, o arquivo fica truncado , ou seja, está completamente vazio. No entanto, não é excluído e recriado.Se um comando começar truncando o arquivo e depois gravar algo nele, e se outro comando fizer o mesmo, a posição do primeiro comando dentro do arquivo não será alterada. Isso significa que você tem dois comandos gravando no mesmo arquivo em duas posições independentes, um possivelmente substituindo a saída do outro, dependendo da ordem de gravação e da quantidade de dados sendo gravados .
Então, sim, os dados no arquivo podem ser uma confusão entrelaçada da saída de ambos os programas, mas dependerá da ordem das gravações no arquivo, bem como da quantidade de dados gravados e do tempo dos truncamentos de o arquivo.
Aqui está um exemplo de entrelaçamento dos dados de dois comandos:
Isto é o que acontece neste script:
hello\n
para ele.123\n
nele. Neste ponto, o ponteiro de arquivo do primeiro comando ainda está apontando para o arquivo em algum deslocamento.world\n
no arquivo.O resultado é um arquivo com um trecho de caracteres nulos no meio:
O nuls (
00
na saída acima) vem do fato de que o ponteiro de arquivo do primeiro comando não foi redefinido pelo truncamento do arquivo do segundo comando, então houve um "buraco" criado. O segundo comando apenas escreveu123\n
, mas teria sobrescrito os nuls se tivesse escrito mais dados:Aqui eu fiz o segundo comando
echo 1234567890
, mas apenas o1234567
é deixado no arquivo. Isso ocorre porque o primeiro comando continua a gravarworld\n
no ponto em que seu ponteiro de arquivo estava depois que o segundo comando terminou de gravar.