解析 mplayer 输出后,Konsole 不显示键入的输入

解析 mplayer 输出后,Konsole 不显示键入的输入

我对下面的脚本有一个非常奇怪的行为。它执行正常,但之后我在提示符下键入的任何内容都会被识别,但不会显示。因此,我可以输入另一个命令或使用箭头按钮从历史记录中选择一个命令,但提示仍然为空。如果我执行新的不可见命令,命令输出将正确显示,但问题仍然存在。只有使用新的终端实例,问题才消失。

#!/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"

我可以将问题缩小到以下范围:

使用 mplayer 输出(见下文),我[[ $line =~ such ]] && echo 9 && break在循环中插入了另一个测试,以顺序检查问题从哪一行开始。

结果:4 号线 (LIRC)。如果测试与之前的任何行匹配,则问题不会发生,否则就会发生。

将 mplayer 输出保存到文件并cat "saved_output"在函数中替换 mplayer 不会引发问题。

那么错误到底出在哪里呢?

mplayer 产生一些奇怪的输出、bash 或我的终端程序(使用 Konsole 和 Yakuake 测试)是否是函数中的错误?

我怎样才能解决这个问题?

# 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)

我的系统:OpenSuse TumbleWeed、KDE

答案1

这是因为当您通过 杀死脚本时Ctrl+C,终端将 SIGINT 发送到前台进程组领导者(在您的情况下,bash 进程是领导者),但默认情况下它不会传递到子 shell 进程。

您可以放在trap "kill 0" SIGINT;脚本之上,例如:

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

或者用一行命令执行此操作:

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

Killing 0 向当前进程组中的所有进程发送信号。信用

当 mplayer 子 shell 在没有 SIGINT 的情况下终止时,其 shell 将不会重置 stty 回显。您可以键入stty echo(在您的情况下不可见)并按Enter以手动启用回显可见性。

相关内容