在 sh 命令中控制通配符扩展
Control wildcard expansion in sh command
我有一个程序使用像 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
无效?
假设DWH_FILEPATTERN_MJF_WLTO
是*
,你有一堆*.xml文件,那么命令就是
dwhDeleteFiles -P *.xml -D ${DWH_DIR_SRC_XML_CURR}/workDir
扩展为
dwhDeleteFiles -P bar.xml baz.xml foo.xml zap.xml -D ${DWH_DIR_SRC_XML_CURR}/workDir
(注意 xml 文件的字母顺序)。但是 -P
选项只需要 one arg,bar.xml
(第一个),其余的被视为文件参数。
尝试在脚本中设置 set -x
以查看实际效果。
我有一个程序使用像 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
无效?
假设DWH_FILEPATTERN_MJF_WLTO
是*
,你有一堆*.xml文件,那么命令就是
dwhDeleteFiles -P *.xml -D ${DWH_DIR_SRC_XML_CURR}/workDir
扩展为
dwhDeleteFiles -P bar.xml baz.xml foo.xml zap.xml -D ${DWH_DIR_SRC_XML_CURR}/workDir
(注意 xml 文件的字母顺序)。但是 -P
选项只需要 one arg,bar.xml
(第一个),其余的被视为文件参数。
尝试在脚本中设置 set -x
以查看实际效果。