O Konsole não mostra entrada digitada após analisar a saída do mplayer

0

Eu tenho um comportamento muito estranho com o script abaixo. Ele é executado corretamente, mas depois disso, qualquer coisa que eu digite no prompt é reconhecida, mas não é exibida. Assim, posso digitar outro comando ou usar os botões de seta para selecionar um do histórico, mas o prompt permanecerá vazio. Se eu executar o novo comando invisível, a saída do comando será exibida corretamente, mas o problema permanece. Apenas com uma nova instância de terminal, o problema desapareceu.

#!/bin/bash

getAspect () {
    aspectR=$(
        mplayer -vo null -nosound "$1" 2>&1 |
        while read line; do  # wait until mplayer prints aspect infos or starts to play
            [[ $line =~ Aspe[ck]t.is.*1\.33:1 ]] && echo 1 && break
            [[ $line =~ Aspe[ck]t.is.*0\.56:1 ]] || [[ $line =~ Aspe[ck]t.is.*1\.78:1 ]] && echo 2 && break
            [[ $line == "VO: [null]"* ]] && echo 0 && break
        done
    pkill -n mplayer
    )
    return $aspectR  # returns 1 (4:3), 2 (16:9) or 0 (no aspect ratio)
}

getAspect "./NameOfAMovieFile"

Eu poderia reduzir o problema para o seguinte:

Usando a saída do mplayer (veja abaixo) eu inseri outro teste [[ $line =~ such ]] && echo 9 && break no loop para verificar sequencialmente em qual linha o problema começou.

Resultado: Linha 4 (LIRC) . Se o teste corresponder a qualquer linha anterior, o problema não ocorreu, senão aconteceu.

Salvar a saída do mplayer para o arquivo e substituir o mplayer por cat "saved_output" na função não levantou o problema.

Então onde está o erro?

É um bug na função, o mplayer está produzindo alguma saída estranha, bash ou meus programas de terminal (testados com o Konsole e o Yakuake)?

Como posso corrigir isso?

# mplayer -vo null -nosound "./NameOfAMovieFile" 2>&1
MPlayer 1.2.r38008-Packman-8 (C) 2000-2017 MPlayer Team
do_connect: could not connect to socket
connect: No such file or directory
Failed to open LIRC support. You will not be able to use your remote control.

Playing ./NameOfAMovieFile.
libavformat version 58.12.100 (external)
libavformat file format detected.
[lavf] stream 0: video (h264), -vid 0
[lavf] stream 1: audio (vorbis), -aid 0, -alang eng
VIDEO:  [H264]  1280x720  0bpp  29.970 fps    0.0 kbps ( 0.0 kbyte/s)
==========================================================================
Opening video decoder: [ffmpeg] FFmpeg's libavcodec codec family
libavcodec version 58.18.100 (external)
Selected video codec: [ffh264] vfm: ffmpeg (FFmpeg H.264)
==========================================================================
Clip info:
 COMPATIBLE_BRANDS: iso6avc1mp41
 MAJOR_BRAND: dash
 MINOR_VERSION: 0
 ENCODER: Lavf57.71.100
Load subtitles in ./
Audio: no sound
Starting playback...
Movie-Aspect is 1.78:1 - prescaling to correct movie aspect.
VO: [null] 1280x720 => 1280x720 Planar YV12  [zoom]
V:   0.0   0/  0 ??% ??% ??,?% 0 0 [J
V:   0.0   0/  0 ??% ??% ??,?% 0 0 [J


MPlayer interrupted by signal 2 in module: sleep_timer
V:   3.1   0/  0 19%  0%  0.0% 0 0 [J

Exiting... (Quit)

Meu sistema: OpenSuse TumbleWeed, KDE

    
por casiosmu 07.10.2018 / 16:04

1 resposta

0

É porque quando você mata o script por Ctrl + C , o terminal envia SIGINT para o líder do grupo de processos em primeiro plano (no seu caso, bash process é o líder), mas não passa para subshell processo por padrão.

Você pode colocar trap "kill 0" SIGINT; em cima do script, por exemplo:

#!/bin/bash
trap "kill 0" SIGINT;
mplayer -vo null foo.mkv 2>&1 | while read line; do echo "$line"; done

Ou faça isso no comando de uma linha:

bash -c 'trap "kill 0" SIGINT; mplayer -vo null foo.mkv 2>&1 | while read line; do echo "$line"; done' 

Killing 0 envia o sinal para todos os processos no grupo de processos atual. Crédito .

Quando o subshell mplayer é finalizado sem o SIGINT, seu shell não será reconfigurado. Você pode digitar stty echo (invisível no seu caso) e pressionar Enter para ativar novamente a exibição da visibilidade manualmente.

    
por 27.11.2018 / 22:36