아래 스크립트에서는 매우 이상한 동작이 발생합니다. 정상적으로 실행되지만 나중에 프롬프트에 입력하는 내용은 인식되지만 표시되지 않습니다. 따라서 다른 명령을 입력하거나 화살표 버튼을 사용하여 기록에서 하나를 선택할 수 있지만 프롬프트는 비어 있습니다. 새로운 보이지 않는 명령을 실행하면 명령 출력이 올바르게 표시되지만 문제는 지속됩니다. 새로운 터미널 인스턴스에서만 문제가 사라졌습니다.
#!/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
또는 한 줄 명령으로 이 작업을 수행합니다.
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에코 가시성을 수동으로 활성화할 수 있습니다.