具有全局值的 Bash 脚本单引号参数

Eri*_*k S 5 bash shell-script wildcards

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

out=$(grep -TInr$C$W --color=always \
    --exclude={translations} \
    --exclude-dir={build,tmp} \
    "$SEARCH")
Run Code Online (Sandbox Code Playgroud)

$C$W变量通过脚本参数配置不区分大小写和确切的词匹配设置,而$SEARCH仅仅是其余的参数,这将是搜索字符串。但是,我忽略某些文件的实现还没有完全奏效。

为了从搜索中排除文件,我尝试使用一个~/.codesearch_config文件,如下所示:

#!/bin/bash

if [[ $PWD == "$HOME/project"* ]]; then
    exclude_directories={.git,build,tmp}
    exclude_files={translations}
fi
Run Code Online (Sandbox Code Playgroud)

当然,这里的想法是根据您当前的工作目录,将加载一组特定的排除项。但是当尝试将这些添加到脚本时:

--exclude=$exclude_files

bash 将整个参数放在单引号中(使用-x调试选项进行测试),如下所示:

grep -TInrw --color=always '--exclude={translations}' '--exclude-dir={build,tmp}' search_term
Run Code Online (Sandbox Code Playgroud)

我想要它做的是将其扩展到--exclude-dir=build --exclude-dir=tmp. 如果我手动将这些$exclude_变量的值添加到命令中,它会扩展得很好;问题只是单引号放在我的参数和 glob 周围。我怎样才能防止这种情况?

cas*_*cas 3

尝试使用数组作为排除项,并将它们扩展为 --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
Run Code Online (Sandbox Code Playgroud)

稍后,您将像这样使用它们:

out=$(grep -TInr$C$W --color=always \
      $exclude_files \
      $exclude_directories \
      "$SEARCH")
Run Code Online (Sandbox Code Playgroud)

注意:这里的变量周围没有引号$exclude_*,否则它们将被视为单个参数,而不是多个--exclude--exclude-dir参数。这是极少数您不想也不应该双引号变量的情况之一(即,当您在一个或多个变量中构造命令行时)。

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