tar 排除在 bash 脚本中不起作用

tar exclude is not working inside the bash script

我正在尝试创建一个文件夹的 tar 文件,其中有很多文件要排除。所以我写了一个脚本(mytar):

#!/usr/bin/env bash

# more files to be included 
IGN=""
IGN="$IGN --exclude='notme.txt'"

tar --ignore-failed-read $IGN -cvf "" ""

# following command is working perfectly
# bash -c "tar --ignore-failed-read $IGN -cvf '' ''"

测试文件夹:

test/
    notme.txt
    test.txt
    test2.txt 

如果我执行脚本,它会创建一个 tar 文件,但不会排除我在 IGN[=44= 中列出的文件] 显然,命令是:

tar --ignore-failed-read --exclude='notme.txt' -cvf test1.tar test  

如果命令直接在 shell 中执行,则该命令运行良好。我还找到了脚本的解决方法:在脚本文件

中使用 bash -c
bash -c "tar --ignore-failed-read $IGN -cvf '' ''"

我想知道并试图弄清楚,

为什么这个简单的命令在没有 bash -c 的情况下不起作用?
为什么要与 bash -c 一起使用?

输出:
第一个输出不应该像后面的
那样包含 notme.txt 文件

更新 1 脚本已更新

这与 bash 在其 shell 中扩展变量的方式有关。

当您设置:

IGN="--exclude='notme.txt'"

它将扩展为:

tar --ignore-failed-read '--exclude='\''notme.txt'\''' -cvf test1.tar test  

因此 tar 将寻找排除名为 \''notme.txt'\'' 的文件,它不会找到。

您可以使用:

IGN=--exclude='notme.txt'

在 shell 扩展后会被正确解释并且 tar 会知道,但我宁愿建议您使用变量只存储要排除的文件名:

IGN="notme.txt"
tar --exclude="$IGN" -cvf ./test1.tar ./*

在下面的命令中,单引号是语法上的(不是字面的,文件名参数不是字面上用引号引起来的)以防止 shell 在包含 space 或制表符的情况下拆分参数

tar --ignore-failed-read --exclude='notme.txt' -cvf test1.tar test  

最接近的是使用数组而不是字符串变量:

ign=( --exclude='notme.txt' )
tar --ignore-failed-read "${ign[@]}" -cvf test1.tar test