如何防止环境变量中的符号转义?

如何防止环境变量中的符号转义?

我正在尝试编写一个 shell 脚本,为了使其更具可读性,我决定将部分命令放入环境变量中:

#!/bin/bash
# Variables

name_expression="-type d \( -name .folder1 -o -name .wildcardfolder* -o -name .folder2 \)"

# Commands

find /root/ -maxdepth 1 "$name_expression" -execdir rm -rf {} \;
find /home/ -maxdepth 2 "$name_expression" -execdir rm -rf {} \;

问题是,如果我尝试运行这个 shell,许多符号都会用引号引起来:

bash -x ./my_shell.sh 
+ name_expression='-type d \( -name .android -o -name .AndroidStudio* -o -name .gradle \)'
+ find /home/ /root/ -maxdepth 2 '-type d \( -name .folder1 -o -name .wildcardfolder* -o -name .folder2 \)' -execdir rm -rf '{}' ';'
find: unknown predicate `-type d \( -name .folder1 -o -name .wildcardfolder* -o -name .folder2 \)'

有什么方法可以在不修改的情况下传递这个变量吗?

答案1

name_expression=( -type d \( -name .folder1 -o -name .wildcardfolder\* -o -name .folder2 \) )

find /root/ -maxdepth 1 "${name_expression[@]}" -execdir rm -rf {} \;

它使用数组参数,而不是必须不加引号才能使命令看到多个部分的字符串参数。这样,可以控制拆分和引用(不是完全控制,即每个部分,而是以适合此任务的方式)。

另一种允许完全控制的替代方法是使用,eval但这会使命令行的其余部分更加复杂。

答案2

避免潜在危险的全局扩展的修改版本:

cleanupdir() {
  # args should be dirname, maxdepth
  find "$1" -maxdepth "$2" -type d \( -name .folder1 -o -name '.wildcardfolder*' -o -name .folder2 \) -execdir rm -rf {} \;
}

cleanupdir /root 1
cleanupdir /home 2

相关内容