以下のスクリプトでは非常に奇妙な動作が発生します。正常に実行されますが、後でプロンプトに入力した内容は認識されますが、表示されません。したがって、別のコマンドを入力するか、矢印ボタンを使用して履歴から1つを選択できますが、プロンプトは空です。新しい見えないコマンドを実行すると、コマンド出力が正しく表示されますが、問題は解決しません。新しい端末インスタンスでのみ問題が消えました。
#!/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プロセスがリーダー)に送信しますが、デフォルトではサブシェルプロセスに渡されないためです。
trap "kill 0" SIGINT;
次のようにスクリプトの上に置くことができます。
#!/bin/bash
trap "kill 0" SIGINT;
mplayer -vo null foo.mkv 2>&1 | while read line; do echo "$line"; done
または、1行のコマンドでこれを行います。
bash -c 'trap "kill 0" SIGINT; mplayer -vo null foo.mkv 2>&1 | while read line; do echo "$line"; done'
0 を終了すると、現在のプロセスグループ内のすべてのプロセスにシグナルが送信されます。クレジット取引。
mplayerサブシェルがSIGINTなしで終了すると、そのシェルはsttyエコーをリセットしません。stty echo
(あなたの場合は見えません)を入力して押して、Enterエコーの可視性を手動で有効にすることができます。