【发布时间】:2018-02-14 17:50:59
【问题描述】:
我有一个程序使用sh -c "<command_string>" 之类的调用来执行shell 函数。我无法改变调用这些函数的方式。
在这个程序中,我调用了不同的自写辅助 shell 函数,这些函数来源于我的环境。其中之一看起来像这样。它将具有给定文件模式的文件解压缩到给定目录中。
function dwhUnzipFiles() {
declare OPTIND=1
while getopts "P:F:T:" opt; do
case "$opt" in
P) declare FILEPATTERN="$OPTARG" ;;
F) declare FROMDIR="$OPTARG" ;;
T) declare TODIR="$OPTARG" ;;
*) echo "Unbekannte Option | Usage: dwhUnzipFiles -P <filepattern> -F <fromdir> -T <todir>"
esac
done
shift $((OPTIND-1))
for currentfile in "${FROMDIR}"/"${FILEPATTERN}" ; do
unzip -o "$currentfile" -d "${TODIR}";
done
# error handling
# some more stuff
return $?
}
对于这个函数,我对FILEPATTERN 变量使用带有通配符的参数。我的程序调用该函数,如下所示:
sh -c ". ~/dwh_env.sh && dwhUnzipFiles -P ${DWH_FILEPATTERN_MJF_WLTO}.xml.zip -F ${DWH_DIR_SRC_XML_CURR} -T ${DWH_DIR_SRC_XML_CURR}/workDir" 其中${DWH_FILEPATTERN_MJF_WLTO} 包含通配符。
这按预期工作。我的困惑始于另一个帮助函数,它以类似的方式构造,但我无法正确控制通配符扩展。它只是根据给定的文件模式删除目录中的文件。
function dwhDeleteFiles() {
declare retFlag=0
declare OPTIND=1
while getopts "D:P:" opt; do
case "$opt" in
D) declare DIRECTORY="$OPTARG" ;;
P) declare FILEPATTERN="$OPTARG" ;;
*) echo "Unbekannte Option | Usage: dwhDeleteFiles -D <Directory> -P <Filepattern>"
esac
done
shift $((OPTIND-1))
for currentfile in "${DIRECTORY}"/"${FILEPATTERN}" ; do
rm -fv "${currentfile}";
done
# error handling
# some more stuff
return $retFlag
}
这个函数是这样调用的:
sh -c ". ~/dwh_env.sh && dwhDeleteFiles -P ${DWH_FILEPATTERN_MJF_WLTO}.xml -D ${DWH_DIR_SRC_XML_CURR}/workDir" 再次 ${DWH_FILEPATTERN_MJF_WLTO} 包含通配符。当我用我的程序调用这个函数时,它什么也不做。我试图尝试将"" 和\"\" 添加到我的函数的参数中,但所发生的一切是,该函数不是删除给定目录中的所有文件,而是只删除按字母数字顺序排列的第一个文件。
有人可以向我解释一下,这里发生了什么吗?我的想法是包含通配符的变量的多次传递不起作用。但是我该如何解决这个问题,甚至在 bash 中是否可行?为什么dwhUnzipFiles函数有效而dwhDeleteFiles无效?
【问题讨论】:
-
function dwhUnzipFiles() {在 sh 中无效 - 这是仅限 bash 的语法。 (声明函数的标准方法是dwhUnzipFiles() {,前面没有function关键字)。如果使用sh -c '...'调用此代码,则此代码将无法在sh由bash以外的shell 提供的平台上可靠运行。 -
无论如何,在函数启动之前,你的函数的命令行被分解成一个参数列表。您不可能从函数本身内部更改它。
-
关于你一直在玩的文字引号——请参阅BashFAQ #50。只有句法引号很重要;文字引号对全局扩展没有影响,除非它们被视为要匹配的模式的一部分。
-
感谢您澄清这一点。我会看看 BashFAQ。