A substituição do processo de bash é interrompida quando a listagem é vinculada

0
TLDR:

cat <(INPUTRC=/dev/null bash -c 'bind -pm emacs') # freezes

# I can't use this because I need to pipe the output of the bind
cat <(INPUTRC=/dev/null bash -c 'bind -pm emacs' &) # doesn't freeze

# I can use this. This won't work for comm below since it takes two file inputs.
cat < <(INPUTRC=/dev/null bash -c 'bind -pm emacs') # doesn't freeze

# I can use this.
cat <(INPUTRC=/dev/null bash -c 'bind -pm emacs') & fg # doesn't freeze

# I can use this. This is my current solution
cat <(INPUTRC=/dev/null bash -c 'bind -pm emacs') | cat # doesn't freeze

Por que congelar e por que o plano de fundo é corrigido? Este diz que tem algo a ver com EOF , por isso estaria esperando em stdin . Existe uma maneira de injetar um EOF ? E por que estaria faltando um EOF ?

Eu não sei se isso é um bug ou se estou fazendo algo errado.

Estou usando o bash-4.4.12 (1) - libero o macOS, mas testei usando gnu-grep e gnu-sort on e obtive os mesmos resultados.

Eu estou tentando comparar as ligações padrão do bash usando a substituição de processos, então não preciso criar arquivos extras.

É assim que estou obtendo as ligações padrão para o emacs. Eu executo um comando bash com um INPUTRC vazio. O grep é para remover ligações desnecessárias e o sort é para que eu possa comparar essas associações emacs com as vi usando comm depois. Recebi este comando de aqui .

INPUTRC=/dev/null bash -c 'bind -pm emacs' |
LC_ALL='C' grep -vE '^#|: (do-lowercase-version|self-insert)$' |
sort

Da mesma forma, veja como obter as ligações vi-insert padrão. Basta substituir emacs por vi-insert

INPUTRC=/dev/null bash -c 'bind -pm vi-insert' |
LC_ALL='C' grep -vE '^#|: (do-lowercase-version|self-insert)$' |
sort

Agora, eu quero comparar esses dois com comm , então eu envolvo esses dois comandos com a substituição de processos e executo comm neles.

comm \
  <(INPUTRC=/dev/null bash -c 'bind -pm emacs' |
    LC_ALL='C' grep -vE '^#|: (do-lowercase-version|self-insert)$' |
    sort) \
  <(INPUTRC=/dev/null bash -c 'bind -pm vi-insert' |
    LC_ALL='C' grep -vE '^#|: (do-lowercase-version|self-insert)$' |
    sort)

saída:

bash: line 0: bind: warning: line editing not enabled
bash: line 0: bind: warning: line editing not enabled
... (empty. I have to press CTRL+C to exit)

Para simplificar, por enquanto, isso também congela

cat <(INPUTRC=/dev/null bash -c 'bind -pm emacs')

Então, eu encontrei este que diz "backgrounding" com & ajuda, e funciona.

cat <(INPUTRC=/dev/null bash -c 'bind -pm emacs' &) # works, has output, no freeze

Então, agora eu tento aplicar esse conhecimento ao comando original, mas não consigo, porque há um pipe.

...'bind -pm emacs' &|... # doesn't work
...'bind -pm emacs' |&... # doesn't work, this is for redirecting stderr to stdout

Então eu tento abordar a coisa toda. Anexe & no final desse longo comando. fg imediatamente para manter um comando de uma linha. Isso funciona

comm \
  <(INPUTRC=/dev/null bash -c 'bind -pm emacs' |
    LC_ALL='C' grep -vE '^#|: (do-lowercase-version|self-insert)$' |
    sort) \
  <(INPUTRC=/dev/null bash -c 'bind -pm vi-insert' |
    LC_ALL='C' grep -vE '^#|: (do-lowercase-version|self-insert)$' |
    sort) & fg

Piping to cat também corrige isso

comm \
  <(INPUTRC=/dev/null bash -c 'bind -pm emacs' |
    LC_ALL='C' grep -vE '^#|: (do-lowercase-version|self-insert)$' |
    sort) \
  <(INPUTRC=/dev/null bash -c 'bind -pm vi-insert' |
    LC_ALL='C' grep -vE '^#|: (do-lowercase-version|self-insert)$' |
    sort) | cat

Notei que quando tento fechar o terminal com o comando de congelamento, esses processos ainda estão em execução. Então, o CTRL + C não pára esses comandos

Alguém sabe o que está acontecendo?

    
por dosentmatter 09.12.2017 / 02:23

0 respostas