编辑(2月24日):有关额外信息,示例和代码,请参阅帖子的底部。
最近工作中出现了一些停机时间,因此我决定采用一些Bash脚本并自动化构建产品的过程。这是我们设置的简化版本:
set-env
和build
脚本(因此脚本目录可以包含libs-set-env.sh
,old-if-set-env.sh
,new-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函数,然后让该函数调用其他两个脚本,但遇到了同样的问题。
所以......请告诉我,好吗?
为简单起见,我减少了可能出现的情况。让我们假设我将使用以下选项和参数运行我的脚本:
~/myscript.sh -c -v ver.3.0 --debug
其中-c
只设置了一些标志,-v
使得我需要在构建命令的末尾添加“ver.3.0”,而--debug
是build
处理的参数。 1}}脚本,它不是我自己的(所以我需要传递它,如果提供的话)。
通常,我的脚本应该执行以下操作:
对这些没什么好看的。我重置OPTIND变量以确保我总是阅读所有内容
OPTIND=1
while getopts "cv:" OPTION; do
"c") echo "Option -c" ;;
"v") echo "Option -v ( = ${OPTARG})" ;;
"?") echo "Unknown option."
done
setenv
命令并运行它 setenv
和build
脚本都设计用于处理命令行参数,但我自己从未将任何内容传递给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
选项,我们将把它的值作为唯一的命令行变量“?
build
命令并运行它还没有。