![stdin에서 읽을 때 mplayer에서 콘솔 입력을 유지하는 방법은 무엇입니까?](https://linux55.com/image/20531/stdin%EC%97%90%EC%84%9C%20%EC%9D%BD%EC%9D%84%20%EB%95%8C%20mplayer%EC%97%90%EC%84%9C%20%EC%BD%98%EC%86%94%20%EC%9E%85%EB%A0%A5%EC%9D%84%20%EC%9C%A0%EC%A7%80%ED%95%98%EB%8A%94%20%EB%B0%A9%EB%B2%95%EC%9D%80%20%EB%AC%B4%EC%97%87%EC%9E%85%EB%8B%88%EA%B9%8C%3F.png)
나는 놀고 있어요명령줄 인터페이스의 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/tty
fd 3은 fd 0이 이전에 읽은 위치에서 읽고, fd 0은 에서 읽습니다 /dev/tty
. </dev/tty 3<&0
fd 0과 fd 3은 동시에 읽혀집니다 /dev/tty
.
답변2
답변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가 대화형 응용 프로그램을 실행하도록 하려는 경우 유용합니다.