我正在尝试编写一个 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