对多个命令重复使用相似的标志

对多个命令重复使用相似的标志

假设我想执行多个具有类似标志的命令,例如:

du -sh / --exclude=/dir1 --exclude=/dir2 --exclude=/dir3/dir4
tar cvf archive / --exclude=dir1 --exclude=dir2 --exclude=dir3/dir4

我想重用标志序列--exclude并使代码更干净,例如将这些标志保存到变量中。

所以之后上面的命令看起来像

du -sh / "$EFLAGS"
tar cvf archive / "$EFLAGS"

请注意,tar排除相对于给定目录的文件和目录。

最好、最干净的解决方案是什么?

背景

我想使用 tar 备份我的系统并排除一些我不需要的目录。

答案1

你可以试试这个:

$ echo -e / --exclude=/dir1 --exclude=/dir2 --exclude=/dir3/dir4
/ --exclude=/dir1 --exclude=/dir2 --exclude=/dir3/dir4
$ echo !!:3-$
echo --exclude=/dir1 --exclude=/dir2 --exclude=/dir3/dir4
--exclude=/dir1 --exclude=/dir2 --exclude=/dir3/dir4

这里我们使用bash历史扩展:

  • !!参考最后一条命令
  • 3-$参考第三个参数到最后一个

bash您应该在脚本中打开历史扩展功能,该功能在非交互式 shell 中被禁用:

set -o history
set -o histexpand

答案2

在 Bash 中,一种非常简洁的方法是使用数组:

myflags=( --exclude=/dir1 --exclude=/dir2 --exclude=/dir3/dir4 )
tar cvf archive / "${myflags[@]}"

他们可以处理空格和任何其他有趣的字符:

myflags=( "--exclude=/a dir/with spaces" $'--exclude=/a dir/with\nnewlines' )
tar cvf archive / "${myflags[@]}"

它们也可以被伪造,例如,您想要排除 目录 中/this/one包含字母的所有子目录g

exclude_dirs=( /this/one/*g* )
myflags=( "${exclude_dirs[@]/#/--exclude=}" )
tar cvf archive / "${myflags[@]}"

答案3

我本来会将此添加为评论,但我还没有弄清楚如何很好地格式化评论!

无论如何,我相信你已经成功了 90%。尝试:-

EFLAGS="--exclude=/dir1 --exclude=/dir2"
du -sh / $EFLAGS
tar cvf archive / $EFLAGS

第一行需要引号,因为涉及空格。

使用变量时不加引号,以便在空格上分割参数。

如果排除的目录名称中有空格,您需要将其转义。

相关内容