linux - 读取 : read error: 0: Resource temporarily unavailable when calling scripts using case in bash

标签 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 中。

最佳答案

看看您的菜单,有些东西没有意义。在您调用的每个案例陈述中:

(exec "./script1")

那是调用./script1作为命令,而不是单独的脚本。其次,因为您将行括在括号中 () ,您强制在 subshel​​l 而不是当前 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 转换了 TABSSPACES , 因此要使用显示缩进的代码,您需要确保代码前面的空格是 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/

相关文章:

linux - Laravel - Linux(ubuntu) 实时处理并在网页上显示输出( Blade )

linux - `ssh -vT git@github.com` 工作正常,代理在 github ssh key 中。问题在哪里?

linux - 带线路缓冲的并发 UART 输出

linux - 使用 xen 镜像获取目录大小

bash - 将变量添加到 awk 命令

创建文件时自动在服务器之间传输 Linux 文件

linux - 查找文件直到一个数字并执行操作

bash - 如何退出期望返回的 bash 函数

linux - 如何在shell脚本中调用./etc/bash_completion?

linux - 此脚本不会按年龄正确排序