Bash 脚本单引号参数与通配值

Bash 脚本单引号参数与通配值

我正在尝试编写一个代码搜索脚本,其中包含可配置的目录和排除的文件。该脚本的主要部分是以下行:

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参数。这是极少数您不想也不应该双引号变量的情况之一(即,当您在一个或多个变量中构造命令行时)。

在几乎所有其他情况下,作为一种根深蒂固的习惯,您应该对变量加双引号。

相关内容