bash循环文件神秘bug
谁能告诉我这里发生了什么 这: 就我所见,它工作得非常好,但是如果我真的尝试运行mplayer而不是响应命令:bash循环文件神秘bug,bash,while-loop,stdin,mplayer,Bash,While Loop,Stdin,Mplayer,谁能告诉我这里发生了什么 这: 就我所见,它工作得非常好,但是如果我真的尝试运行mplayer而不是响应命令: find . -name "*.mp3" | while read fname ; do echo "$fname"; ls "$fname"; mplayer "$fname" ; echo "$fname" ; done 然后它播放一个文件,然后失控 我认为mplayer一定是以某种方式与read交互的,但我对bash的方式并不明
find . -name "*.mp3" | while read fname ; do
echo "$fname";
ls "$fname";
mplayer "$fname" ;
echo "$fname" ;
done
然后它播放一个文件,然后失控
我认为mplayer一定是以某种方式与read交互的,但我对bash的方式并不明智。你的猜测是正确的
find
将其文件列表输出到stdout
。您可以将其导入第二个进程:您的while
循环。在这个循环中,read
和mplayer
都从stdin
读取read
将读取第一个文件名,mplayer
将读取所有其余的输入,就像您在运行时通过键盘控制它一样
最简单的解决方案是添加
使用mplayer
的-noconsollecontrols
选项。它使它忽略了标准输入,因此它不会从中窃取字符,read
可以处理这些字符,mplayer
不会表现出奇怪的行为,将文件名解释为来自键盘的命令。改为:
#!/bin/env bash
while IFS= read -r -d '' fname <&9; do
printf '%s\n' "$fname"
ls "$fname"
mplayer "$fname"
printf '%s\n' "$fname"
done 9< <(find . -name '*.mp3' -print0)
#/bin/env bash
虽然IFS=read-r-d“fname谢谢你,你是某种了不起的bash天才,我会尽快接受你的回答!不要将用于循环和带有find | read
的YMMV,请参阅。9
是一个任意选择的文件描述符编号,在其他地方尚未使用。你可以选择你喜欢的任何数字,只要是免费的,这主要意味着>2。对,我使用9是因为常见问题解答使用9,我希望OP能够清楚/轻松地看到常见问题解答解决方案如何应用于他的问题。
#!/bin/env bash
while IFS= read -r -d '' fname <&9; do
printf '%s\n' "$fname"
ls "$fname"
mplayer "$fname"
printf '%s\n' "$fname"
done 9< <(find . -name '*.mp3' -print0)