Select 在循环中不要求输入
Select in loop don't ask for input
我想循环提问(例如,要求确认处理目录中的每个文件)。
这段代码完美运行:
PS3="Dummy question ? "
select CHOICE_MADE in "Ans1" 'Ans2' 'Ans3'; do
if [[ -n ${CHOICE_MADE} ]]; then
printf "Choice made : %s\n" "${CHOICE_MADE}"
break;
fi
done
我需要循环这个问题(注意我在循环中命名变量,以避免使用默认的 $REPLY 变量):
while read -r TOTO; do
PS3="Dummy question ? "
select CHOICE_MADE in Ans1 Ans2 Ans3; do
if [[ -n ${CHOICE_MADE} ]]; then
printf "Choice made : %s\n" "${CHOICE_MADE}"
break;
fi
done
done < <(echo Step1 Step2)
Select 不提示任何内容。
我不想使用 whiptail(屏蔽脚本先前的输出)、对话框(需要在 debian 上安装)或任何图形用户界面。
我知道我可以使用 read 来解决我的问题,但我想保持 select 循环。
在此先感谢您的帮助。
你必须注意两件事才能让它发挥作用。
1) `stdin` 使用不当
首先,将 < (echo Step1 Step2)
传递给您的 while
循环,您正在使用 stdin
,这就是提示根本不等待任何输入的原因(它已经有!)。
您可以使用 file descriptors:
来摆脱它
exec 3< <(echo Step1 Step2) ### Create fd "3" and put output of echo in it
while read -r TOTO <&3; do
PS3="Dummy question ? "
select CHOICE_MADE in Ans1 Ans2 Ans3; do
if [[ -n ${CHOICE_MADE} ]]; then
printf "Choice made : %s\n" "${CHOICE_MADE}"
break
fi
done
done
exec 3>&- ### clean fd 3
其余代码我保持不变。
2) `read` 的错误使用
你要想到的另一件事是,read -r
会逐行读取你给他的内容,而一个简单的echo Step1 Step2
只会产生一行,所以你会循环只是一次。
为了摆脱这种不需要的行为,您将不得不使用其他解决方案。
目前我能想到的一个解决方案是heredoc:
exec 3<< EOF
Step1
Step2
EOF
while read -r TOTO <&3; do
PS3="Dummy question ? "
select CHOICE_MADE in Ans1 Ans2 Ans3; do
if [[ -n ${CHOICE_MADE} ]]; then
printf "Choice made: %s\n" "${CHOICE_MADE}"
break
fi
done
done
exec 3>&- ### clean fd 3
请注意,不建议使用多个 heredoc,最佳实践建议改用实际文件,因为脚本应该包含逻辑,而不是数据。
我想循环提问(例如,要求确认处理目录中的每个文件)。
这段代码完美运行:
PS3="Dummy question ? "
select CHOICE_MADE in "Ans1" 'Ans2' 'Ans3'; do
if [[ -n ${CHOICE_MADE} ]]; then
printf "Choice made : %s\n" "${CHOICE_MADE}"
break;
fi
done
我需要循环这个问题(注意我在循环中命名变量,以避免使用默认的 $REPLY 变量):
while read -r TOTO; do
PS3="Dummy question ? "
select CHOICE_MADE in Ans1 Ans2 Ans3; do
if [[ -n ${CHOICE_MADE} ]]; then
printf "Choice made : %s\n" "${CHOICE_MADE}"
break;
fi
done
done < <(echo Step1 Step2)
Select 不提示任何内容。
我不想使用 whiptail(屏蔽脚本先前的输出)、对话框(需要在 debian 上安装)或任何图形用户界面。
我知道我可以使用 read 来解决我的问题,但我想保持 select 循环。
在此先感谢您的帮助。
你必须注意两件事才能让它发挥作用。
1) `stdin` 使用不当
首先,将 < (echo Step1 Step2)
传递给您的 while
循环,您正在使用 stdin
,这就是提示根本不等待任何输入的原因(它已经有!)。
您可以使用 file descriptors:
来摆脱它exec 3< <(echo Step1 Step2) ### Create fd "3" and put output of echo in it
while read -r TOTO <&3; do
PS3="Dummy question ? "
select CHOICE_MADE in Ans1 Ans2 Ans3; do
if [[ -n ${CHOICE_MADE} ]]; then
printf "Choice made : %s\n" "${CHOICE_MADE}"
break
fi
done
done
exec 3>&- ### clean fd 3
其余代码我保持不变。
2) `read` 的错误使用
你要想到的另一件事是,read -r
会逐行读取你给他的内容,而一个简单的echo Step1 Step2
只会产生一行,所以你会循环只是一次。
为了摆脱这种不需要的行为,您将不得不使用其他解决方案。
目前我能想到的一个解决方案是heredoc:
exec 3<< EOF
Step1
Step2
EOF
while read -r TOTO <&3; do
PS3="Dummy question ? "
select CHOICE_MADE in Ans1 Ans2 Ans3; do
if [[ -n ${CHOICE_MADE} ]]; then
printf "Choice made: %s\n" "${CHOICE_MADE}"
break
fi
done
done
exec 3>&- ### clean fd 3
请注意,不建议使用多个 heredoc,最佳实践建议改用实际文件,因为脚本应该包含逻辑,而不是数据。