Linux 如何制作;焦油——不包括;在*nix环境中表现一致?

Linux 如何制作;焦油——不包括;在*nix环境中表现一致?,linux,macos,bash,Linux,Macos,Bash,我正在编写一个bash脚本来进行部署tarball,该脚本必须跨OSX和Linux工作 我有一个如下所示的目录结构,在bash脚本中,我需要对不包括/foo但包括/baz/foo的内容进行tar $ find . . ./bar ./baz ./baz/foo ./foo 简单!通常我会通过将--exclude='./foo'传递给tar命令来实现这一点,但我发现--exclude=pattern的行为在OSX和CentOS中是不同的 我的问题是,如何最好地克服这一点?如何使两个环境的行为相同

我正在编写一个bash脚本来进行部署tarball,该脚本必须跨OSX和Linux工作

我有一个如下所示的目录结构,在bash脚本中,我需要对不包括
/foo
但包括
/baz/foo
的内容进行tar

$ find .
.
./bar
./baz
./baz/foo
./foo
简单!通常我会通过将
--exclude='./foo'
传递给tar命令来实现这一点,但我发现
--exclude=pattern
的行为在OSX和CentOS中是不同的

我的问题是,如何最好地克服这一点?如何使两个环境的行为相同,或者至少检测到所需的更改

或者,有人能为他们证实这种行为吗(OSX 10.11),这样我就知道我没有什么奇怪的环境了

CentOS按预期工作:

$ tar zcfv ../test.tar.gz --exclude='./foo' .
./
./bar/
./baz/
./baz/foo/
OSX的行为不同:

$ tar zcfv ../test.tar.gz --exclude='./foo' .
a .
a ./bar
a ./baz
在阅读了几个小时的文档之后,我没有发现任何东西可以解释这种不同的行为,但是通过反复试验,我发现使用插入符号来表示模式的开始在OSX上是有效的

OSX的修复程序(使用插入符号):

但在CentOS上不起作用:

$ tar zcfv ../test.tar.gz --exclude='^./foo' .
./
./bar/
./foo/
./baz/
./baz/foo/
最后,我注意到OSX使用的是bsdtar而不是GNU tar,所以这是问题的根源吗

OSX:

CentOS:

$ tar --version
tar (GNU tar) 1.23

谢谢你的评论。在实现
--exclude=pattern
时,这似乎是bsdtar和GNU tar之间的一个根本区别,并且没有办法使它们的行为相同

由于我可以控制操作系统环境,我可以接受的解决方法是使用brew在OSX上安装GNU tar(谢谢@Seer)。然后,我在脚本中使用以下命令来检测安装的tar是否为GNU,如果不是,则返回到gtar。如果未安装gtar,它将中止

# OSX uses bsdtar which causes problems with --exclude=pattern
# so force use of gtar if non-GNU tar detected
tar --version | grep -q 'gnu'
if [ $? -eq 0 ]
then
    echo "Detected GNU tar - using tar"
    TAR_BIN=`command -v tar 2>&1` || { echo >&2 "I require tar but it is not installed. Aborting."; exit 1; }
else
    echo "Detected non-GNU tar - using gtar"
    TAR_BIN=`command -v gtar 2>&1` || { echo >&2 "I require gtar but it is not installed. Aborting."; exit 1; }
fi

# this will now work consistently as GNU tar is always used
$TAR_BIN zcfv ../test.tar.gz --exclude='./foo' .

注意:CentOS实际上至少将gtar别名为tar,因此可以安全地假设使用gtar命令,但我更喜欢上述方法。

一个选项是使用brew在OSX上安装GNU tar。我能想到的唯一其他可行方法是对安装的tar版本进行某种检查(即,在脚本中写入一些内容,检查用户是否正在使用GNU tar或bsdtar,然后在某些情况下使用这些内容来决定如何运行tar。可能是@davidcondrey的重复-这与问题不同question@Seer-是的,我认为使用brew安装GNU tar可能是我唯一的出路-这远不是一个理想的解决方案ugh.可能需要检查安装的tar版本和脚本中的操作系统,如果操作系统是Darwin,则确保gnu tar可用,如果不可用则退出。本质上,问题在于
--exclude
是BSD tar不完全模仿的非标准选项,但基于gnu tar的选项。
$ tar --version
tar (GNU tar) 1.23
# OSX uses bsdtar which causes problems with --exclude=pattern
# so force use of gtar if non-GNU tar detected
tar --version | grep -q 'gnu'
if [ $? -eq 0 ]
then
    echo "Detected GNU tar - using tar"
    TAR_BIN=`command -v tar 2>&1` || { echo >&2 "I require tar but it is not installed. Aborting."; exit 1; }
else
    echo "Detected non-GNU tar - using gtar"
    TAR_BIN=`command -v gtar 2>&1` || { echo >&2 "I require gtar but it is not installed. Aborting."; exit 1; }
fi

# this will now work consistently as GNU tar is always used
$TAR_BIN zcfv ../test.tar.gz --exclude='./foo' .