Bash - 内部读取-u 3而不工作

时间:2014-03-13 13:54:07

标签: bash

我试图在while循环中运行一个read命令来获取用户输入,如下所示:

for dir in ./*; do   
    for subdir in $dir/*; do   
        someprocess |  
        sort_processed_pipedout |  
        tail_sortedout |  
        while read line; do   
            another_process on $line  
            read -t 1 -n 10000 discard   
            read -u 3 -p "Save as final? (y/n)" USER_INPUT  
            if [ "$USER_INPUT" = y ]; then   
                                something_else  
                echo "success"  
            fi  
        done 3<&0  
    done  
done  

这就是我认为我在做的事情:

对于尾部输出的每一行(基本上每行一个文件名),第一次读取忽略任何无意的输入,第二次读取切换“文件句柄”。从0到3(如给定的here),其余的照常进行。

这里发生了什么: USER_INPUT似乎直接来自尾部输出。

为什么这会失败?

编辑:如何将其输出到同一个子shell?

2 个答案:

答案 0 :(得分:3)

请参阅BashFAQ #24 - 如果你想重定向stdin,你需要提前做到这一点,而它仍然指向终端,而不是在它指向输出之后管道。但最好不要那样做,而只是将你的管道放在另外的FD上:

for subdir in ./*/*; do   
    while read -r -u 3 line; do   
        : another_process on "$line"
        read -t 1 -n 10000 discard   
        read -p "Save as final? (y/n)" user_input
        if [[ $user_input = y ]]; then
            : something_else  
            echo "success"  
        fi  
    done 3< <(someprocess | sort_processed_pipeout | tail_sortedout)
done

答案 1 :(得分:1)

0表示当前标准输入,不一定是终端,因此您仍然只是将管道从tail复制到文件描述符3.将重定向向下移动到下一个循环。

for dir in ./*; do   
    for subdir in $dir/*; do   
        someprocess |  
        sort_processed_pipedout |  
        tail_sortedout |  
        while read line; do   
            another_process on $line  
            read -t 1 -n 10000 discard   
            read -u 3 -p "Save as final? (y/n)" USER_INPUT  
            if [ "$USER_INPUT" = y ]; then   
                                something_else  
                echo "success"  
            fi  
        done  
    done   3<&0
done

(Charles Duffy的回答有一些更好的改进,所以我会选择那个而不是这个最小的修复。)