假设我想执行多个具有类似标志的命令,例如:
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
第一行需要引号,因为涉及空格。
使用变量时不加引号,以便在空格上分割参数。
如果排除的目录名称中有空格,您需要将其转义。