读取:读取错误:0:使用bash中的case调用脚本时资源暂时不可用

时间:2015-06-10 23:46:51

标签: linux bash shell

我正在尝试创建一个菜单,允许用户在当前目录中调用某些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。

1 个答案:

答案 0 :(得分:2)

查看菜单有一些不合理的事情。在您的每个案例陈述中,您都可以致电:

(exec "./script1")

这是将./script1称为命令,而不是单独的脚本。第二,因为你将这一行括在parens ()中,你强迫执行在子shell 而不是当前的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