Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 打印出开关所有外壳的列表_Bash - Fatal编程技术网

Bash 打印出开关所有外壳的列表

Bash 打印出开关所有外壳的列表,bash,Bash,奇怪的问题。是否可以在bash中自动打印某个开关箱的所有箱?在某种程度上,它尽可能保持可维护性,这意味着如果添加了新的案例来打印相同的案例,则不必再添加任何代码 例如,如果案例表示命令,这将非常有用。然后,帮助功能可以打印出所有可用的命令 不知道我是否正确理解了您的问题,但您可以做一些事情,例如打印所有可用案例作为默认选择: case "$1" in start) start ;; stop) stop ;;

奇怪的问题。是否可以在bash中自动打印某个开关箱的所有箱?在某种程度上,它尽可能保持可维护性,这意味着如果添加了新的案例来打印相同的案例,则不必再添加任何代码


例如,如果案例表示命令,这将非常有用。然后,帮助功能可以打印出所有可用的命令

不知道我是否正确理解了您的问题,但您可以做一些事情,例如打印所有可用案例作为默认选择:

case "$1" in
    start)
        start
        ;;

    stop)
        stop
        ;;

    status)
        status anacron
        ;;
    restart)
        stop
        start
        ;;
    condrestart)
        if test "x`pidof anacron`" != x; then
            stop
            start
        fi
        ;;

    *)
        echo $"Usage: $0 {start|stop|restart|condrestart|status}"
        exit 1

esac

bash
不允许您访问它解析的令牌,也不保存
case
字符串(也可以是glob表达式)


不幸的是,这意味着您将无法按希望的方式干燥代码。

没有直接的方法来实现这一点,但您可以使用数组来维护您的选择:

# Define your choices - be sure not to change their order later; only
# *append* new ones.
choices=( foo bar baz )

# Make the array elements the case branches *in order*.
case "$1" in
    "${choices[0]}")
        echo 'do foo'
        ;;

    "${choices[1]}")
        echo 'do bar'
        ;;

    "${choices[2]}")
        echo 'do baz'
        ;;

    *)
        echo "All choices: ${choices[@]}"

esac
这会降低分支的可读性,但如果仔细维护阵列,这是一个可管理的解决方案

注意分支条件是如何包含在
“…”
中的,以防止shell将值解释为(类全局)模式

也就是说,正如所指出的,您可能希望将您的选择定义为模式,以匹配字符串的变化:

在这种情况下:

  • 选项
    数组中用引号定义模式;e、 例如,
    choices=(foo-bar-baz'h*)

  • 案例
    分支中引用它;e、 例如,
    ${choices[3]}


在对Bash 4的几个功能进行了一段时间的整合后,我得到了这一个

#!/bin/bash

set -euo pipefail 

# create coprocess with 2 descriptors so we can read and write to them
coproc CAT { cat ; }

# creme de la creme of this solution - use function to both collect and select elements
function element {
    echo "$1" >&${CAT[1]}
    echo "$1"
}   

case "$1" in
    $(element A))
            echo "Your choice is: A"
    ;;

    $(element B))
            echo "Your choice is: B"
    ;;

    *)
            echo "Your choice is not present in available options: $1"
            # close writing descriptor
            exec {CAT[1]}>&-
            #read colected options into an array
            mapfile -t OPTIONS <&${CAT[0]}

            echo "Available options are: [ ${OPTIONS[@]} ]"

    ;;
esac
此解决方案分为两部分:

  • coproc
    -它创建用于从子shell读取和写入的子进程
  • 函数
    元素
    ,它既写入
    coproc
    子进程的描述符,又返回它的参数,因此我们可以在
    案例中使用它。。。esac
如果处理所有选项都应该在
案例
之外进行,那么您可以使用
&case
语句的code>特性,它强制检查
case
中的每个语句(通常-即
-在第一次匹配后停止)。需要进行此检查,以便稍后将所有选项收集到一个数组中


不使用此选项可能有很多原因(可以安全存储在描述符中的数据限制,而不必读取它们),我欢迎所有可以使此解决方案更好的注释。

您可以让脚本自行检查:

#/bin/bash
案例#开始=$(“$LINENO”+2))#开始的存储行号
案件“$1”
简单案例)呼应“这很容易”;;
--(棘手)
echo“这是一个棘手的问题”
(回声“多行”)
附和“声明”
;;
-(帮助)呼应“heeelpme”;;
-q |——安静);;
*)呼应“未知选项”;;
以撒
案例结束=$(“$LINENO”-2))#存储结束的行号
#-在$case\u start和$case\u end之间划线
#-用空格替换换行符
#-用换行符替换“;”
#->现在每个案例陈述都应该在自己的行上
#-然后过滤掉案例:删除第一个“)”之后的所有内容,包括“)”和修剪空白
cases_available=`sed-n“${case_start},${case_end}p“$0 | sed's/#.*/'| tr'\n''.| sed's//\n/g’| sed’s/)./;s/[:blank:][]*/'`
echo-e“案例可用:\n\n$cases\u可用”
这将打印:

cases_available: simple_case --tricky -h|--help -q|--quiet * 可提供的案例: 简单案例 --狡猾的 -h |——救命 -q |——安静 * 这其中有一些陷阱:

  • case语句中带有“;”的注释或字符串将破坏内容
  • 无法处理嵌套的开关大小写语句

我认为最好的方法,也是在OP方面,就是将开关盒结构打印到一个新文件中,然后根据需要在原始文件中进行源代码转换

在“>case.sh”中回显“case”“$1”
echo“test)”>>case.sh
回声“回声”这个案子!“”>>case.sh
echo“;”>>case.sh
echo“esac”>>case.sh
chmod+x case.sh
/case.sh测试
#这个案子!

通过这种方式,您可以轻松地使用变量来构建开关/案例条件。

这正是我试图避免的。我希望有一些函数
listalcases
(可以自动遍历开关的所有情况)并像这样使用:
*)listalcases
。在我所知道的所有语言中都是不可能的。好吧,没有内置函数。您必须将shell脚本作为文本处理(通过将$0与调用站点信息一起传递给函数),这在bash中当然是可能的,但这并不容易……要正确地做到这一点,您必须在调用站点之前解析shell脚本。我不会在bash中这样做,我会在C中这样做。以前肯定有人这样做过,我现在找不到类似的东西……您可以在注释(pragma)中用唯一的代码标记每个开关的开始和结束,并将其传递到perl/awk脚本(以及$0)。这已经成为。。。。可行。 cases_available: simple_case --tricky -h|--help -q|--quiet *