O que pode fazer com que o `>` falhe silenciosamente no Linux?

20

Eu executei este comando:

python ./manage.py dumpdata partyapp.InvitationTemplate > partyapp_dump.json

Para despejar dados no partyapp_dump.jsonarquivo. Mas todos os dados são impressos na tela e um partyapp_dump.jsonarquivo vazio é criado.

Por que isso pôde acontecer? Eu testei ls > partyapp_dump.jsone isso funcionou perfeitamente.

Ram Rachum
fonte

Respostas:

40

Com > você redireciona apenas a saída padrão. Tente 2> para redirecionar a saída de erro. Use &> para redirecionar ambos.

fabuloso
fonte
11
Para sua informação, &>funcionará apenas no Bash 4.0 e nas versões recentes do zsh do iirc. Para uma solução mais portátil foo > bar 2&>1,. Referência: mywiki.wooledge.org/BashFAQ/014
Rein Henrichs
6
@Rein Henrichs: Isso é 2> & 1, não 2 &> 1
camh
Lembro-me com um pneumônica da programação: '2', a ( '>') o local ( 'e') '1' (?)
hometoast
11
@hometoast: Você quer dizer mnemônico? :) Pneumonic significa pulmão ...
carlpett
22

Seu aplicativo python deve estar gravando sua saída no canal de saída STDERR em vez do STDOUT normal. O uso da construção shell >captura e redireciona apenas os dados gravados no canal de saída, mas na verdade existem vários outros canais que podem ser impressos, sendo o mais comum o segundo, geralmente usado para erros.

Você pode tentar capturar o STDERR (segundo canal) da seguinte maneira:

python ./manage.py dumpdata partyapp.InvitationTemplate > partyapp_dump.json 2>&1

A 2>&1construção conecta o fluxo de saída para erros ao canal de saída normal. É incomum um programa gerar saída que você deseja capturar no canal de erro; geralmente isso seria reservado para informações de depuração, não dados de aplicativos. Por favor, use este script com algum cuidado, pois ele está se comportando de maneira não-padrão.

Você também pode despejar os canais de saída e erro em arquivos diferentes como este:

python ./manage.py dumpdata partyapp.InvitationTemplate > partyapp_dump.json 2> error_output.txt
Caleb
fonte
5

Além da explicação já sugerida da saída stderr vs stdout, seu aplicativo pode simplesmente ignorar esses dois fluxos e abrir explicitamente "/ dev / tty" para sua saída.

jlliagre
fonte
1

Se a noclobberopção bash estiver definida, o redirecionamento falhará (embora não silenciosamente) se o arquivo de destino já existir.

Para uma melhor portabilidade, use cmd >| filepara forçar a substituição de qualquer arquivo existente.

tylerl
fonte
0

Se você estiver perdido, sempre poderá tentar executá-lo com strace para ver o que os processos estão fazendo:

strace -f command
bluszcz
fonte
11
Resposta verdadeira, mas não particularmente relevante. Se o cara não sabia agora sobre o gerenciamento do fluxo de erros, não acho que ele saberá o que fazer com a saída de um strace.
Caleb