我正在尝试创建一个菜单,允许用户调用当前目录中的某些 shell 脚本。菜单循环直到用户退出脚本(输入 5)
到目前为止,这是我的代码:
until [ "$SELECTION" = "5" ]; do
echo "# Enter a number to launch:"
echo "# 1) Script 1"
echo "# 2) Script 2"
echo "# 3) Script 1 and Script 2"
echo "# 4) Readme"
echo "# 5) Exit"
echo -n "Launch: "
read SELECTION
case $SELECTION in
1)
(exec "./script1") ;;
2)
(exec "./script2") ;;
3)
(exec "./script1")
(exec "./script2") ;;
4) vi "readme.txt" ;;
5) exit 0 ;;
*) echo "Error. Please enter a valid selection." ;;
esac
done
用户选择后,所选脚本运行良好,但一旦完成,我会收到重复出现的错误:
read: read error: 0: Resource temporarily unavailable
而且它永远不会返回菜单。 我不确定我做错了什么。有任何想法吗?这是在 bash 中。
最佳答案
看看您的菜单,有些东西没有意义。在您调用的每个案例陈述中:
(exec "./script1")
那是调用./script1
作为命令,而不是单独的脚本。其次,因为您将行括在括号中 ()
,您强制在 subshell 而不是当前 shell 中执行。
您对 SELECTION
的使用在 [ "$SELECTION" = "5" ]
似乎未初始化,(我认为这是你用引号引起来的原因)。引用没有错,但是你的值是1-5
, 所以它不是强制性的,只要它被初始化。
您的菜单本身很好。事实上它多次执行失败是你在 (exec "./script1")
中所做的任何事情的结果。 .由于您似乎正试图从您的 case
调用 bash 脚本语句,启动脚本的正确方法(如果它们没有通过 chmod 0755
执行)是使用 bash
而不是 exec
.如果脚本不是 bash,或者您想概括调用,则使用 exec
将按照评论中提到的方式工作。
虽然until
没有问题(除了不常用),我建议使用 while
.此外,由于您有多个 echo
连续语句,请考虑使用 here
创建 heredoc
的语句反而。
缩进代码使阅读更容易,并使逻辑清晰明了。一个警告是 heredoc
及其结束分隔符。缩进 heredoc
及其分隔符,它们 必须缩进 TABS
不是SPACES
强>。此外,heredoc 必须以 <<-
开头。而不是简单的 <<
利用 TAB
缩进。 (这就是为什么我一开始没有提出这个话题)
稍作重写可能如下所示。 注意:下面的代码是8-space
缩进是因为 SO 转换了 TABS
至 SPACES
, 因此要使用显示缩进的代码,您需要确保代码前面的空格是 TAB
字符而不是 SPACES
或者它不会运行:
declare -i SEL=0
while [ $SEL != 5 ]; do
cat >&2 <<- MENU
Enter a number to launch:
1) Script 1
2) Script 2
3) Script 1 and Script 2
4) Readme
5) Exit
MENU
echo -n " Launch: "
read SEL
case $SEL in
1) echo "./script1"
;;
2) echo "./script2"
;;
3) echo "./script1"
echo "./script2"
;;
4) vi "readme.txt"
;;
5) exit 0
;;
*) echo "Error. Please enter a valid selection."
;;
esac
done
您可以选择是否要正式缩进 heredoc
或不。我更喜欢 4-space
缩进,所以我只留下 heredoc
打开和分隔符没有缩进以保留允许剪切/粘贴示例的能力。您的选择:
declare -i SEL=0
while [ $SEL != 5 ]; do
cat >&2 << MENU
Enter a number to launch:
1) Script 1
2) Script 2
3) Script 1 and Script 2
4) Readme
5) Exit
MENU
echo -n " Launch: "
read SEL
case $SEL in
1) exec "./script1"
;;
2) exec "./script2"
;;
3) exec "./script1"
exec "./script2"
;;
4) vi "readme.txt"
;;
5) exit 0
;;
*) echo "Error. Please enter a valid selection."
;;
esac
done
关于linux - 读取 : read error: 0: Resource temporarily unavailable when calling scripts using case in bash,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30769222/