Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.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 select案例中生成bash脚本_Bash_Shell - Fatal编程技术网

如何在bash select案例中生成bash脚本

如何在bash select案例中生成bash脚本,bash,shell,Bash,Shell,我一直在试图找到一种方法,将选项文件源代码添加到我的案例脚本中,如下所示: 主文件 case "$1" in . options esac 选项文件 #options file 1 ) do som

我一直在试图找到一种方法,将选项文件源代码添加到我的案例脚本中,如下所示: 主文件

case "$1" in                                                                 
. options                                                                      
esac
选项文件

#options file               
1 ) do something
2 ) do something else
有人有什么想法吗?因为我得到的只是一个“解析错误” 提前感谢您的帮助

TL;博士 以下工作很好:

# options
case "$1" in
  1) something ;;
  2) something else ;;
esac
在原始代码中:

. options "$@"
…与您尝试执行的操作不同的是,您正在向选项添加页眉和页脚

解释 。或者源本身就是一个命令。如果不能在某个位置放置任意命令,那么也不能在该位置放置源命令

既然您的选项文件在编写时必须知道它将放在case语句中,为什么不将case和esac行放在其中呢?这并没有降低灵活性:$1可以在源命令本身中重写:

. my.sh "$@" # this passes the current arguments through...
鉴于:

# this still works without changing options
. my.sh "$foo" # this passes $foo as $1
交替丑陋的文字断线 作为一种会破坏大量调试功能的非常丑陋、可怕的黑客,您可以执行以下操作:

# Don't do this; it'll cause headaches later.
eval 'case "$1" in '"$(<options)"'; esac'

您首先需要与$1匹配的东西,否则案例陈述的重点是什么

case "$1" in
 options) . options ;;
 things)  echo "What should I do with things?" ;;
 *) echo "I don't know what you want" ;;
esac
看到更新后,正确的做法是将整个case语句包装到外部文件中定义的函数中

handle_options () {
    case "$1" in 
        1 ) do something ;;
        2 ) do something else ;;
    esac
}
然后从源文件的脚本调用该函数

. somefile
handle_options "$1"

从字里行间看,您真正想要做的是能够从外部源文件中为$1的不同值添加处理程序——可能是任意数量的此类文件,而它们彼此都不知道

这是一件非常好的事情。不要用case来做这件事

考虑以下几点:

# base-options
do__1() { echo "doing something"; }
do__2() { echo "doing something else; }
…也许还有一个单独的文件:

# extra-options
do__foo() { echo "doing yet another thing"; }
现在,从主文件中,您可以在以下文件中找到所有这些文件:

# this loop will source in both base-options and extra-options
for f in *options; do
  source "$f"
done

# and here, if we *have* a command -- either as a shell function or an external command --
# corresponding to our $1, we run that command.
if type "do__$1" >/dev/null; then
  cmd="do__$1"; shift
  "$cmd" "$@"
else
  echo "Handler for $1 not found" >&2
  exit 1
fi
采用上述方法还意味着处理程序根本不需要是shell函数!如果您有一个名为do___1的可执行文件,那么只要它在您的路径中,就可以按类型找到它,这样您就可以用任何您想要的语言编写处理程序—您不会将自己锁定在bash中


这与git处理子命令的方式密切相关——请参阅所有处理git-foo命令的git-foo可执行文件。这是一种常见的做法,也是一种很好的做法。使用它。

你能用你得到的错误发布你的完整代码吗。你的意思是你想替换选项本身吗?你不能那样做。不支持。如果要在foo中执行案例$1。选择权;;以撒,那就很好了。顺便说一句,这真的是一场狂欢/usr/bin/env bash/bin/bash等或POSIX sh/你问的是宾/什?大多数编写bash的人都会使用源代码而不是如果您需要符合POSIX,那么这意味着我的答案的其他部分需要更改,即使用效率较低的$cat foo而不是$BTW-我在这里使用第二个Inian-尽管我知道您遇到的实际错误,但一个好问题包括它的文字,不仅仅是将其描述为“解析错误”。我在阅读OP时说,他们希望将选项(要匹配的内容)放在文件中。啊,是的。哎呀,哎呀。OP显然想用TeX编程。我试图将选项分开,以便以后可以继续添加到选项中,并在fly@chepner,…因此,通过适当使用ESP,我想我已经了解了OP的真正意图。对于是否应该编辑问题以更好地反映相同的问题,你对另一个人的回答是什么?这种方式有效,我可以看到它不整洁,但我的意思是我可以分离选项,然后再添加到它们中,谢谢。这是什么方式?如果你是指黑客,就像我说的,它会破坏一堆调试功能。如果您想使用set-x跟踪程序的执行,LINENO和BASH_SOURCE无法准确地知道执行的源代码来自何处。坦率地说,如果您想构建一个大表并与之匹配,最好在运行时从脚本本身开始执行,完全不尝试使用case。另一件很好用的事情,我在过去做过,就是有一个函数命名的约定-所以你在定义函数时有不同的文件,比如do_1和do_2如果你的case是1和2,那么你看看名为do_$1的函数是否存在,如果存在就调用它。@Chris:…所以,我重申:这里有更好的方法来实现任何合理的现实世界目标,如果你问我们如何最好地实现这个目标,你可能会得到一个根本不包括案例的答案。谢谢你的帮助这正是我想要的对措辞表示歉意