linux - 我如何压缩 proc 文件系统?

标签 linux bash tar

我想拍下我的整个 proc 文件系统的快照,并将其保存在压缩包中(或者在最坏的情况下将所有文本文件连接到一个文本文件中)。

但是当我运行时:

tar -c /proc

我遇到段错误。

执行此操作的最佳方法是什么?我应该设置某种递归遍历每个文件吗?

我只有基本的 *nix 实用程序,例如 bash、cat、ls、echo 等。我没有像 python 或 perl 或 java 这样花哨的东西。

最佳答案

linux/proc 文件系统实际上是伪装成文件系统的内核变量。没有什么可以保存,因此没有什么可以备份。如果系统允许,你可以rm -rf /proc它会在下次重新启动时神奇地重新出现。

/dev 文件系统有真正的 i-nodes 并且它们可以被备份。除了它们没有内容,只有主要和次要编号、权限和名称。备份特殊设备文件的工具只记录这些参数,从不尝试打开 (2) 设备。然而,由于设备的主要和次要编号仅在它们所针对的精确系统上才有意义,因此没有理由备份它们。

尝试 tar/proc 伪文件系统导致 tar 出现段错误的原因是因为/proc 具有有趣的文件行为:诸如只写伪文件之类的东西可能看起来具有读取权限,但如果一个程序试图打开(2)它进行备份。这肯定会驱使天真的 tar 变得小气。

为回应评论而添加

我并不惊讶 tar 在读取/proc/kmsg 时遇到问题,因为它有一些有趣的属性:

# strace cat /proc/kmsg
execve("/bin/cat", ["cat", "kmsg"],
open("kmsg", O_RDONLY|O_LARGEFILE)      = 3
// ok, no problem opening the file for reading
fstat64(3, { st_mode=S_IFREG|0400,  st_size=0,
// looks like a normal file of zero length
// but cat does not pay attention to st_size so it just
// does a blocking read
read(3, "<4>[103128.156051] ata2.00: qc t"..., 32768) = 461
write(1, "<4>[103128.156051] ata2.00: qc t"..., 461) = 461
// ...forever...
read(3, "<6>[103158.228444] ata2.00: conf"..., 32768) = 48
write(1, "<6>[103158.228444] ata2.00: conf"..., 48) = 48
+++ killed by SIGINT +++

因为/proc/kmsg 是内核消息发生时的运行列表,它永远不会返回 0 (EOF),它会一直运行,直到我感到无聊并按 ^C。

有趣的是,我的 tar 在/proc/kmsg 上没有问题:

$ tar --version
tar (GNU tar) 1.22
# tar cf /tmp/junk.tar /proc/kmsg
$ tar tvf /tmp/junk.tar
-r-------- root/root         0 2010-09-01 14:41 proc/kmsg

如果您查看 strace 输出,GNU tar 1.22 会看到 st_length == 0 并且甚至懒得打开文件进行读取,因为那里什么都没有。

我可以想象你的 tar 看到长度为 0,使用 malloc(3) 分配了那么多(无)空间,它尽职尽责地交还了一个指向零长度缓冲区的指针。您的 tar 从/proc/kmsg 读取,获得了非零长度读取,并试图将其存储在零长度缓冲区中,但出现了分段违规。

那只是在/proc 中等待 tar 的一个老鼠洞。还有多少?不知道。他们的行为会相同吗?可能不是。 ~1000 个左右的文件中哪些不是 /proc/<pid>伪文件会有奇怪的语义?不知道。

但也许最有说服力的问题是:您认为/proc/sys/vm/lowmem_reserve_ratio 有什么意义,下周它会有所不同吗?您能从这种差异中学到什么吗?

关于linux - 我如何压缩 proc 文件系统?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3630976/

相关文章:

c++ - ‘.’ token 之前应有非限定 ID

linux - IPC msgsnd 意外等待

linux - 返回当前 UTC 时间字符串的 Bash 函数回显它和 CWD 以及原始文件名

sql-server - 如何编写 bash 和 sql 文件来设置 postgres 用户?

kubernetes - 调用 kubectl cp 命令时如何使用 tar 命令选项

php - 允许通过 PHP 访问 protected 文件

go - 如何在 tar 中获取 tar 中文件的所需路径

linux - Rundeck 身份验证错误甚至添加了正确的 ssh_用户名和密码

Linux屏幕输入自动响应

bash - 用于轮询的 unix wait 命令