stdin에서 읽을 때 mplayer에서 콘솔 입력을 유지하는 방법은 무엇입니까?

stdin에서 읽을 때 mplayer에서 콘솔 입력을 유지하는 방법은 무엇입니까?

나는 놀고 있어요명령줄 인터페이스mplayer. 다음과 같은 방식으로 스크립트를 작성하고 싶습니다.

find /some/path/ -type f | grep -vif blacklist | mplayer -shuffle -playlist -

blacklist아티스트 이름이나 노래 이름이 적힌 텍스트 파일이 어디 있는지, 방문객이 있거나 아들이 근처에 있을 때 무시하는 편이 낫습니다. (욕설이 많이... :D)

mplayer이 문자가 나타나면 -콘솔 입력이 비활성화됩니다. 매뉴얼 페이지에서:

-noconsolecontrols
          Prevent MPlayer from reading key events from standard input.  
          Useful when reading data from standard input.  This is automatically  
          enabled when - is found on the command line. [snip]

이렇게 하면 파일 내에서 개별 노래를 찾거나 건너뛸 수 없습니다. 흥미롭게도 이는 비디오 창에서 여전히 일반적인 키보드 입력을 허용하므로 비디오에 적용됩니다.

일반 콘솔 입력을 어떻게 복원할 수 있나요? 물론 이것이 가장 간단한 해결책이기는 하지만 임시 파일을 사용하는 것을 피하고 싶습니다. -slave그리고 -input그것은 맞지 않는 것 같고 노력해도 -consolecontroles효과가 없는 것 같습니다.

답변1

표준 입력이 아닌 파일 설명자에 입력을 제공합니다.

find /some/path/ -type f | grep -vif blacklist |
mplayer -shuffle -playlist /dev/fd/3 3<&0 </dev/tty

마지막 줄에 대한 설명: grep의 데이터는 표준 입력에서 나옵니다.파일 설명자0. 쉘에서 표준 입력 이외의 다른 것으로 파이프할 수 있는 방법은 없지만 몇 가지 추가 파이핑을 수행할 수 있습니다. 먼저, 파일 설명자 3을 파일 설명자 0의 위치에 연결합니다: 3<&0. 그런 다음 파일 설명자 0(즉, 표준 입력)을 터미널에 연결합니다 </dev/tty. 우리는 mplayer에게 파일 설명자 3에서 재생 목록을 읽도록 지시합니다. mplayer는 파일 이름을 기대하므로 이를 에 전달하고 /dev/fd/3프로세스가 파일을 열면 해당 프로세스의 파일 설명자 3인 것처럼 동작합니다.

리디렉션의 순서는 중요하며 직관이 잘못된 경우 직관에 반할 수 있습니다. 3<&0 </dev/ttyfd 3은 fd 0이 이전에 읽은 위치에서 읽고, fd 0은 에서 읽습니다 /dev/tty. </dev/tty 3<&0fd 0과 fd 3은 동시에 읽혀집니다 /dev/tty.

답변2

이것은 약간 과잉이지만 여전히 실행 가능한 솔루션일 수 있습니다.퓨즈 파일 시스템필터링을 지원합니다.FS 필터링또는로프스 필터.FS 공개매우 편리한 것 같습니다. 누락된 파일을 숨깁니다.user.public 확장된 파일 속성( xattr).

mplayer이들 중 하나를 사용하면 모든 파일을 섞고 제어를 유지할 수 있습니다 stdin. (단, 두 개의 재생목록을 만드는 것에 비하면 상당히 힘든 작업입니다.)

답변3

파일 설명자를 명시적으로 스푸핑하는 대신 Bash에는 파이프를 FD로 전달하는 편리한 방법이 있습니다.

mplayer -shuffle -playlist <(find /some/path -type f -not -name '*.foo')

<(COMMAND)이를 수행하려면 (출력을 명령으로 파이프) 및 (출력을 명령으로 파이프)를 모두 사용할 수 있습니다 . >(COMMAND)일반적으로 /dev/fd/ 파일 이름 대신 /proc/self/fd/ 파일 이름을 사용하여 작동하지만 모든 수고를 하지 않고 효과는 동일합니다.

물론 mplayer는 이 경우 /proc/self/fd에서 재생 목록 파일과 동일한 디렉터리에서 비절대 재생 목록 콘텐츠 파일을 찾습니다. (/dev/fd 솔루션에도 동일하게 적용됩니다.) 매일 명령의 stdout을 통해 수동으로 입력 <()하거나 다른 쪽 끝에서 해당 데이터를 선택하지 않고 실행되는 명령에서 종료 코드를 캡처 할 수 없습니다 >(). 이는 작동하지 않습니다. 명령줄 사용에는 중요하지 않지만 스크립팅에는 문제가 될 수 있습니다.

답변4

xargs -o다음과 같은 옵션을 사용할 수 있습니다 .

find /some/path/ -type f -print0 2>/dev/null | grep -vif blacklist | xargs -0 -o mplayer -shuffle

man xargs:

-o, --open-tty

명령을 실행하기 전에 하위 프로세스에서 /dev/tty로 stdin을 다시 엽니다. 이는 xargs가 대화형 응용 프로그램을 실행하도록 하려는 경우 유용합니다.

관련 정보