参数&多个Bash脚本中的选项操作

时间:2014-02-21 22:47:22

标签: linux bash shell unix scripting

编辑(2月24日):有关额外信息,示例和代码,请参阅帖子的底部。

最近工作中出现了一些停机时间,因此我决定采用一些Bash脚本并自动化构建产品的过程。这是我们设置的简化版本:

  • 有三种类型的代码库 - 基本库,旧接口和新接口
  • 构建分两步完成 - #1设置环境(al变量)和#2编译可执行文件/包;这两个都是用脚本完成的,其中一些是命令行参数,一些不是
  • 每个代码库使用不同的set-envbuild脚本(因此脚本目录可以包含libs-set-env.shold-if-set-env.shnew-if-set-env.sh,{{ 1}}等等......)

因此。我想要做的是创建一些(组合)Bash函数和脚本:

  • 检测我目前在哪个代码库的目录
  • 解析任意数量的命令行选项/参数。我一直在尝试使用libs-build.sh
    • 有些选项只是标记(例如getopts表示详细输出)而有些选项需要值(例如 - -v
  • 运行相应的version 3.0脚本
  • 运行相应的set-env脚本

首先,我尝试将所有这些放在一个build文件中。我遇到了一个问题,其中一些构建脚本会尝试读取我自己的命令行参数,就好像它们是针对它们的那样。所以我会运行类似.sh的内容,并会收到类似

的错误
~/myscript.sh -v

因为~/scripts/build-base-libs.sh: line X: cd: -v: invalid option cd: usage: cd [-L|-P] [dir] 检查参数是以build-base-libs.sh还是--debug传递给它,如果不是(例如,--release),它会对待它作为文件路径并将其传递给-v调用。这对于原始脚本来说很好,但它会弄乱我的包装器。所以问题#1 :我仍然可以将所有内容放在一个.sh文件中,但不知何故可以避免这个问题(只调用原始命令行的子集或不调用相应的cd脚本争论,也许?)?

如果这不起作用,我尝试拆分功能 - 所以我会使用mysetenv.sh和mybuild.sh,并让前者通过我自己的命令行参数进行解析,然后用任何一个或不用任何一个来调用后者原始选项(因此,如果我运行build,我可以选择是使用~/mysetenv.sh -g -version 3.0~/mybuild.sh-g,还是两者都使用-version 3.0。除了我显然不太了解Bash才能运行 - 当我运行~/mysetenv.sh时,我实际上看不到任何我应该从mybuild.sh看到的输出。我怀疑它与子进程和子shell有关,但我只是不知道...我也尝试在~/.bashrc中创建一个小的bash函数,然后让该函数调用其他两个脚本,但遇到了同样的问题。

所以......请告诉我,好吗?

---编辑(2月24日)---

为简单起见,我减少了可能出现的情况。让我们假设我将使用以下选项和参数运行我的脚本:
~/myscript.sh -c -v ver.3.0 --debug
其中-c只设置了一些标志,-v使得我需要在构建命令的末尾添加“ver.3.0”,而--debugbuild处理的参数。 1}}脚本,它不是我自己的(所以我需要传递它,如果提供的话)。

通常,我的脚本应该执行以下操作:

1)解析(我的自定义)选项

对这些没什么好看的。我重置OPTIND变量以确保我总是阅读所有内容

OPTIND=1
while getopts "cv:" OPTION; do
    "c") echo "Option -c" ;;
    "v") echo "Option -v ( = ${OPTARG})" ;;
    "?") echo "Unknown option."
done

2)选择setenv命令并运行它

setenvbuild脚本都设计用于处理命令行参数,但我自己从未将任何内容传递给setenv s - 仅传递给build s,甚至那么只有当参数是-v选项的值时。所以我的setenv脚本是/development/scripts/setenv_script.sh,我想要运行

. /development/scripts/setenv_script.sh # no options, ignoring that --debug from before

首先,不要忽略--debug(因为即使没有${@:OPTIND}部分,我也会得到完全相同的错误):

SETENV_COMMAND=". /development/scripts/setenv_script.sh" # Which will then call setenv_script_2.sh, which will call setenv_script_3.sh
echo eval "${SETENV_COMMAND} ${@:OPTIND}"
eval "${SETENV_COMMAND} ${@:OPTIND}" # I believe this should call the SETENV_COMMAND with anything after the OPTIND index...

我收到以下错误:

eval . /development/scripts/setenv_script.sh
/development/scripts/setenv_script_2.sh: line 104: cd: ver.3.0: No such file or directory

setenv_script_2.sh的相关部分包括:

60 for option in $*; do
61     case $option in
62         "--release") ... ;;
63         "--debug") ... ;;
64         "--help") ... ;;
65         *) src_path=$option ;;
66     esac
67 done
...
103 if [ -n "${src_path}" ]; then
104     src_dir=$(cd -P ${src_path}; pwd -P)
105 else
106     src_dir=$(pwd -P)

所以,据我所知,setenv_script.sh被调用时没有参数(如echo所示;虽然我希望得到--debug ...),这就是我想要的,但 it 所调用的一个脚本仍然将“ver.3.0”视为一个参数 - 我不希望它。我希望将“ver.3.0”传递给build脚本,并使setenv运行时不带参数。

我有办法更新$@ / $*吗?因此,在我阅读了我的选项后,我可以说“好吧,有0个命令行参数,运行setenv_script.sh传递给它及其子项”?然后,当我完成该操作时,我可以说“好吧,现在让我们运行build.sh,但如果设置了-v选项,我们将把它的值作为唯一的命令行变量“?

3)选择build命令并运行它

还没有。

0 个答案:

没有答案