我正在尝试编写一个代码搜索脚本,其中包含可配置的目录和排除的文件。该脚本的主要部分是以下行:
out=$(grep -TInr$C$W --color=always \
--exclude={translations} \
--exclude-dir={build,tmp} \
"$SEARCH")
$C
和变量$W
由脚本参数设置,以配置不区分大小写和精确的单词匹配,并且$SEARCH
只是剩余的参数,这将是搜索字符串。但是,我忽略某些文件的实现还不太有效。
要从搜索中排除文件,我尝试使用一个~/.codesearch_config
文件,如下所示:
#!/bin/bash
if [[ $PWD == "$HOME/project"* ]]; then
exclude_directories={.git,build,tmp}
exclude_files={translations}
fi
当然,这里的想法是,根据您当前的工作目录,将加载一组特定的排除项。但是当尝试将这些添加到脚本中时:
--exclude=$exclude_files
bash 会将整个参数放在单引号中(使用-x
调试选项进行测试),如下所示:
grep -TInrw --color=always '--exclude={translations}' '--exclude-dir={build,tmp}' search_term
我想要它做的是将其扩展到--exclude-dir=build --exclude-dir=tmp
.如果我手动将这些变量的值添加$exclude_
到命令中,它就会很好地扩展;问题只是单引号放在我的参数和全局变量周围。我怎样才能防止这种情况发生?
答案1
尝试使用数组作为排除项,并将它们扩展为 --exclude-dir
和--exclude
选项。
例如在您的~/.codesearch_config
脚本中(大概这是由您的主脚本来源的?):
#! /bin/bash
# temporary array variables
declare -a __exclude_directories
declare -a __exclude_files
if [[ "$PWD" == "$HOME/project"* ]]; then
__exclude_directories=(.git build tmp)
__exclude_files=(translations)
elif [[ "$PWD" == "/some/where/else" ]]; then
__exclude_directories=(foo bar)
__exclude_files=(abc.txt def.txt xyz.txt)
fi
exclude_directories=''
exclude_files=''
for i in "${__exclude_directories[@]}" ; do
exclude_directories+=" --exclude-dir '$i'"
done
for i in "${__exclude_files[@]}" ; do
exclude_files+=" --exclude '$i'"
done
unset __exclude_directories
unset __exclude_files
# comment out or delete the next two lines after you've verified
# that the output is correct.
echo $exclude_directories
echo $exclude_files
稍后,您将像这样使用它们:
out=$(grep -TInr$C$W --color=always \
$exclude_files \
$exclude_directories \
"$SEARCH")
注意:这里的变量没有引号$exclude_*
,否则它们将被视为单身的参数每个而不是多个--exclude
和--exclude-dir
参数。这是极少数您不想也不应该双引号变量的情况之一(即,当您在一个或多个变量中构造命令行时)。
在几乎所有其他情况下,作为一种根深蒂固的习惯,您应该对变量加双引号。