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