tar提取后,更改权限

时间:2010-05-23 13:31:47

标签: php unix file-permissions tar

关于unix和PHP的问题。

我在PHP上做的是使用Unix系统来解压缩tar文件。

exec("tar -xzf foo.tar.gz");

一般情况下一切正常,直到遇到这个特殊的foo.tar.gz,其文件系统如下:

Applications/
Library/
Systems/

运行tar命令后,似乎文件权限变为644(而不是755)。

这会导致Permission denied (errno 13),因此会禁用我的大部分代码。 (我猜测是因为缺乏特权)

我能以任何方式阻止这个tar命令彻底破坏我的权限吗?

感谢。

哦,这似乎只有在我有一个具有这个特定文件系统的foo.tar.gz文件时才会发生。别的什么,我很好。

2 个答案:

答案 0 :(得分:2)

如果要保留文件的权限,则必须在解压缩tarball时添加-p(或--preserve-permissions或--same-permissions)开关。来自tar手册页:

--preserve-permissions
--same-permissions
-p
    When `tar' is extracting an archive, it normally subtracts the
    users' umask from the permissions specified in the archive and
    uses that number as the permissions to create the destination
    file.  Specifying this option instructs `tar' that it should use
    the permissions directly from the archive.

所以PHP代码应该是:

exec("tar -xzfp foo.tar.gz");

答案 1 :(得分:0)

编辑:--delay-directory-restore解决了以下无法解压文件的问题。 pwd的权限仍然有所改变,因此原始海报的问题可能无法解决。

不是一个真正的答案,但是一种重现错误的方法。

首先创建一些文件和目录。删除对目录的写访问权:

mkdir hello
mkdir hello/world
echo "bar" > hello/world/foo.txt
chmod -w hello/world
chmod -w hello

接下来,从目录中创建tar文件,保留权限。

cd hello
tar -cpf ../hw.tar --no-recursion ./ world world/foo.txt
cd ..

列出档案:

tar -tvf hw.tar
# dr-xr-xr-x ./
# dr-xr-xr-x world/
# -rw-r--r-- world/foo.txt

到目前为止,由于" Permission denied" -error,我无法以普通用户的身份解压档案。档案无法存档天真无邪。本地目录的权限也会发生变化。

mkdir untar
cd untar
ls -ld .
# drwxr-xr-x ./
tar -xvf ../hw.tar
# ./
# world/
# tar: world: Cannot mkdir: Permission denied
# world/foo.txt
# tar: world/foo.txt: Cannot open: No such file or directory
# tar: Exiting with failure status due to previous errors
ls -ld .
# dr-xr-xr-x ./

尝试umask和/或-p没有帮助。但是,添加--delay-directory-restore确实有助于解决问题:

tar -xv --delay-directory-restore -f ../hw.tar
# ./
# world/
# world/foo.txt
ls -ld .
# dr-xr-xr-x ./
chmod +w .

也可以以root身份解压缩文件。最令我惊讶的是tar显然可以改变pwd的权限,这仍然没有解决。

顺便说一句,我最初是通过为/ with

创建一个tarball来解决这个问题
tar -cvpzf backup.tar.gz --exclude=/backup.tar.gz --one-file-system /

以root身份(pwd = /)并将其作为普通用户解压缩以创建Linux容器。