Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 选择案例未按预期工作_Linux_Shell_Select_Menu_Case - Fatal编程技术网

Linux 选择案例未按预期工作

Linux 选择案例未按预期工作,linux,shell,select,menu,case,Linux,Shell,Select,Menu,Case,我写了这个案例选择声明,拒绝工作,我无法找出我做错了什么。感谢您的帮助。谢谢 echo; echo "Did you see a display?" select YN in "yes" "no" ; do case $YN in yes) echo "$2 at $X x $Y @$REF Hz">>/root/ran.log break ;; no)

我写了这个案例选择声明,拒绝工作,我无法找出我做错了什么。感谢您的帮助。谢谢

echo; echo "Did you see a display?"
select YN in "yes" "no" ; do
    case $YN in
        yes)
            echo "$2 at $X x $Y @$REF Hz">>/root/ran.log
            break   
        ;;
        no)
            echo "$2 at $X x $Y @$REF Hz">>/root/didntrun.log
            break   
        ;;
    esac
done
这是这部分代码的bash-x输出?在屏幕上重复多次,跳过提示用户并跳转到代码的下一部分

+ echo 'Did you see a display?'
Did you see a display?
+ select yn in '"yes"' '"no"'
1) yes
2) no
#? + case $yn in
#? + case $yn in
#? + case $yn in
#? + case $yn in
#? + case $yn in
#? + case $yn in
#? + case $yn in
#? + case $yn in
#? + case $yn in
#? + case $yn in
#? + case $yn in
#? + case $yn in
#? + case $yn in
#? + case $yn in
#? + case $yn in
#? + case $yn in
#? 
编辑:我想这是因为select代码是在从文件中读取行的循环之间调用的。stdin对文件的更改会导致select跳过用户提示并尝试从文件中读取。现在我需要一个方法来解决这个问题

编辑2: 这是使调用成为fnUseResolution函数的代码,其中包含select语句

res.log的每行分辨率为1920 1080 60等格式

FILE=res.log
BAKIFS=$IFS
IFS=$(echo -en "\n\b")
exec 3<&0
exec 0<$FILE
while read -r LINE
do
    fnUseResolution $LINE app1
    fnUseResolution $LINE app2
    fnUseResolution $LINE app3
done
exec 0<&3
IFS=$BAKIFS

这对我来说很好,它停止并允许我输入1或2

见以下发言稿:

pax$ cat qq.sh
echo "Did you see a display?"
select YN in "yes" "no" ; do
    case $YN in
        yes)
            echo YES
            break   
        ;;
        no)
            echo NO
            break   
        ;;
    esac
done

pax$ ./qq.sh
Did you see a display?
1) yes
2) no
#? 1
YES

pax$ ./qq.sh
Did you see a display?
1) yes
2) no
#? 2
NO

pax$ _
您确定标准输入已在该点连接到您的终端吗

由于您已经证实了我的怀疑,即您的标准输入没有连接到终端,因此有一种比较棘手的方法可以通过摆弄文件句柄来修复它

考虑以下代码,该代码实现了您在注释中指出的功能,即调用从重定向标准输入的循环中接受标准输入的函数:

fn() {
    echo "Did you see a display?"
    select YN in "yes" "no" ; do
        case $YN in
            yes)
                echo YES $YN $REPLY
                break
            ;;
            no)
                echo NO $YN $REPLY
                break
            ;;
        esac
    done
}

echo 'A
B
C
D' | while read ; do
    echo $REPLY
    fn
    echo ====
done
如果运行此代码,您将看到:

A
Did you see a display?
1) yes
2) no
#? #? #? #? 
=====
这表明在读取和选择时,输入在两个读卡器之间混合

解决此问题的诀窍是通过如下更改代码来解除两个读卡器的关联:

(echo 'A
B
C
D' | while read ; do
    echo $REPLY
    fn <&4
done) 4<&0
而且,根据您的代码,一个很好的起点可能是围绕整个地块来保留标准输入,例如:

(FILE=res.log
BAKIFS=$IFS
IFS=$(echo -en "\n\b")
exec 3<&0
exec 0<$FILE
while read -r LINE
do
    fnUseResolution $LINE app1 <&4
    fnUseResolution $LINE app2 <&4
    fnUseResolution $LINE app3 <&4
done
exec 0<&3
IFS=$BAKIFS) 4<&0
用于读取的-u4选项将其tels为使用文件句柄4而不是0,我已经更改了exec以匹配该选项。我还没有测试过,但应该可以用


通过这样做,您永远不会更改标准输入,因此函数中的输入应该是正常的。此外,在这种情况下,没有理由将其保存/还原到文件句柄3中,因此我对那些exec调用进行了注释。

这应该可以工作;Bash将用户响应返回到变量$REPLY。 如果您键入是或否,则此选项将起作用

echo; echo "Did you see a display?"
select YN in "yes" "no" ; do
    case $REPLY in
        yes)
            echo "$2 at $X x $Y @$REF Hz">>/root/ran.log
            break   
        ;;
        no)
            echo "$2 at $X x $Y @$REF Hz">>/root/didntrun.log
            break   
        ;;
        *)
            echo "blah! blah! $REPLY"
            break
    esac
done

这里的标题让我想到这不起作用,它返回$REPLY中输入的值,换句话说,是2而不是否。您需要调整大小写位。找出它不起作用的原因:select语句在一个函数中,该函数在一个循环中调用,该循环每次从一个文件读取一行输入。由于select处于文件读取之间,因此stdin会更改文件,并且无法提示用户输入。知道怎么解决这个问题吗?@fzkl:是的,有,虽然很复杂。请看更新。嗯。。这让人困惑,尤其是因为我不太熟悉文件处理。我已经用处理读取的部分代码更新了我的原始帖子。您的解决方案将如何应用?谢谢你的信息。我只需要自己去学。
(FILE=res.log
BAKIFS=$IFS
IFS=$(echo -en "\n\b")
exec 3<&0
exec 0<$FILE
while read -r LINE
do
    fnUseResolution $LINE app1 <&4
    fnUseResolution $LINE app2 <&4
    fnUseResolution $LINE app3 <&4
done
exec 0<&3
IFS=$BAKIFS) 4<&0
FILE=res.log
BAKIFS=$IFS
IFS=$(echo -en "\n\b")
#exec 3<&0
exec 4<$FILE
while read -u 4 -r LINE
do
    fnUseResolution $LINE app1
    fnUseResolution $LINE app2
    fnUseResolution $LINE app3
done
#exec 0<&3
IFS=$BAKIFS
echo; echo "Did you see a display?"
select YN in "yes" "no" ; do
    case $REPLY in
        yes)
            echo "$2 at $X x $Y @$REF Hz">>/root/ran.log
            break   
        ;;
        no)
            echo "$2 at $X x $Y @$REF Hz">>/root/didntrun.log
            break   
        ;;
        *)
            echo "blah! blah! $REPLY"
            break
    esac
done