我有一个包含超过 400 GiB 数据的目录。我想检查所有文件是否可以正确读取,所以我想到的一个简单方法是将tar其放入/dev/null. 但相反,我看到了以下行为:
$ time tar cf /dev/null .
real 0m4.387s
user 0m3.462s
sys 0m0.185s
$ time tar cf - . > /dev/null
real 0m3.130s
user 0m3.091s
sys 0m0.035s
$ time tar cf - . | cat > /dev/null
^C
real 10m32.985s
user 0m1.942s
sys 0m33.764s
Run Code Online (Sandbox Code Playgroud)
上面的第三个命令在运行了很长时间后被Ctrl+强行停止C。此外,当前两个命令正在工作时,包含的存储设备的活动指示器.几乎总是空闲的。使用第三个命令时,指示灯会持续亮起,表示非常忙碌。
所以看起来,当tar能够发现它的输出文件是 时/dev/null,即当/dev/null直接打开有tar写入的文件句柄时,文件体似乎被跳过了。(添加v选项tar确实将目录中的所有文件打印为tar“红色”。)
所以我想知道,为什么会这样?这是某种优化吗?如果是,那么为什么还要tar对这种特殊情况进行如此可疑的优化?
我在 Linux …
假设我有一个 X 应用程序,它使用键盘和鼠标作为其正常操作模式(例如 QEMU),但是由于某个地方的错误,它非常难以挂起(例如陷入磁盘睡眠)。通常我会kill(1)从远程终端杀死一个应用程序,但如果应用程序处于磁盘睡眠模式,它就不能真正被杀死。我可以通过xkill实用程序终止此应用程序与 X 服务器的连接,但是这次我不能这样做,因为鼠标被抓住了,因此xkill将无法运行。
那么,如果我愿意牺牲这个客户端,但我无法通过操作系统的方式杀死它,我如何从 X 客户端的抓取中释放我的键盘和鼠标?
我正在尝试查看/tmp/目录中的文件数。为此,我认为此命令会起作用:
watch sh -c 'ls /tmp/|wc -l'
Run Code Online (Sandbox Code Playgroud)
但它似乎工作得好像ls没有参数一样。即,我在~,并且我在那里获得了文件数量而不是/tmp/. 我找到了一个解决方法,它似乎有效:
watch sh -c 'ls\ /tmp/|wc -l'
Run Code Online (Sandbox Code Playgroud)
但是,为什么我要逃避之间的空间ls和/tmp/?命令如何转换,watch以便将ls输出提供给wc,但/tmp/不作为参数传递给ls?
在许多不同的机器上,当我碰到死机,我经常使用Alt+ SysRq+ REISUB,以重启没有太多的损失。但是我经常注意到,虽然REISU命令即使我只是按住Alt+SysRq并输入它们而不释放Alt+ SysRq,但最后一个,B,似乎很“懒惰”:我必须重复很多次,实际上它不会触发直到我多次执行循环“按Alt+ SysRq,键入 B,释放Alt+ SysRq”(并不总是相同的次数)。
最初出现这个问题时,我以为是内核锁定得太厉害,以至于它没有“看到”我的B命令,但是当我意识到它的多次重复确实允许我触发重新启动时,现在看来它是通用的. 即使在工作系统(无论是 Debian、Ubuntu、LFS 等)上,我也可以轻松地重现这一点。事实上,我什至可以init=/bin/bash从这个 bash 提示符加载内核并重现它。
查看串行控制台输出,我看到了关于 的所有反馈REISU,但在多个B命令上只打印了一个反馈——当内核最终被说服进行重新启动时。
为什么是这样?是某些内核功能可以防止意外重置,还是只是一个错误(很奇怪)?
请注意,我用普通键盘没有Fn或多媒体快捷键,所以这个问题不是重复这一个。
我正在尝试发出一个sed命令,以便将超过 3 位的数字转换为十六进制。即像这样的字符串124 3275 7535应该导致124 0xccb 0x1d6f. 这是我目前拥有的:
sed 's@\([0-9]\{4,\}\)@sh -c "printf 0x%x \1"@ge'
Run Code Online (Sandbox Code Playgroud)
但是当字符串不匹配时,它会尝试将未更改的字符串作为外部命令运行,因此对于上面的示例字符串,我得到
sh:1:124:未找到
我怎样才能实现我想要做的事情(最好还在使用sed)?
在 USB 主控制器连接到 PCI/PCIE 总线的任何 PC 上,我会看到以下内容:
\n$ cat /sys/bus/usb/devices/usb1/{idVendor,idProduct,manufacturer,product,serial}\n1d6b\n0002\nLinux 4.14.157-amd64-x32 ehci_hcd\nEHCI Host Controller\n0000:00:1a.0\nRun Code Online (Sandbox Code Playgroud)\n即,EHCI 主机控制器(在本例中具有 PCI 设备位置0000:00:1a.0)由一组虚假的字符串描述符和供应商/产品标识符表示。查找供应商 ID 1d6b,usb.ids发现它对应于 Linux Foundation。(lsusb将其列为“Linux Foundation 2.0 root hub”。)但是所引用的 PCI 设备serial是真实的,并且具有以下属性:
$ cat /sys/bus/pci/devices/0000:00:1a.0/{vendor,device}\n0x8086\n0x8c2d\nRun Code Online (Sandbox Code Playgroud)\n查找这些 ID,我们可以发现它是 Intel 8 系列/C220 系列芯片组系列 USB EHCI(与所说的pci.ids相同)。lspci来自真正硬件制造商的真正硬件。
那么为什么 Linux 用一些奇怪的 id 集来表示这个 Intel 硬件呢?我确实意识到 PCI 和 USB 供应商/产品 id 可能会发生冲突,因此不可能使用 PCI 命名空间中的 id 启动 USB 设备树。但为什么是字符串描述符呢?
\n我的猜测是,这是因为名为“*HCI Host Controller”的整个 …
我已通过设置禁用内存过度使用overcommit_memory=2。现在,当我尝试时swapoff,出现此错误:
swapoff:/dev/sda5:swapoff 失败:无法分配内存
但我实际上有0 MiB交换和大量可用内存!我尝试设置overcommit_ratio为 100,但它没有改变任何东西。
如果我暂时overcommit_memory=0按默认设置,我可以成功swapoff,然后重新禁用过度提交。
为什么会有这种奇怪的行为?这是一个错误吗?
按照评论中的要求进行编辑:
$ grep -E '^Mem|Commit' /proc/meminfo
MemTotal: 2044420 kB
MemFree: 751836 kB
CommitLimit: 4122112 kB
Committed_AS: 2752544 kB
Run Code Online (Sandbox Code Playgroud) lspci 给我以下信息:
$ lspci|grep VGA
01:00.0 VGA compatible controller: NVIDIA Corporation GF104 [GeForce GTX 460] (rev a1)
Run Code Online (Sandbox Code Playgroud)
这都是正确的,但这是 GPU 的通用名称。但是驱动程序管理器 ——KDE 控制模块——给了我更多有趣的信息:最重要的是安装驱动程序的选项说
NVIDIA Corporation N460GTX Cyclone 1GD5/OC
Run Code Online (Sandbox Code Playgroud)
这正是供应商 (MSI) 给它起的名字。
如何在不使用 KDE 实用程序的情况下找出这些名称?我更喜欢基于控制台的解决方案。
换句话说,KCM 这个名字从何而来?
假设我更改了一些用户设置,例如其初始登录组或将其添加到新组。我现在可以su user使用这些新设置。但是所有以前运行的进程仍将具有与以前相同的权限。
如何强制特定运行的进程重新读取/etc/passwd并/etc/group重新初始化其用户和组设置,而不终止它正在执行的任何活动?我试过用gdb和 do附加到进程print setuid(MY_USER_ID),但尽管结果是0(即成功),进程仍然保持相同的数据(检查bash运行groups以查看是否出现了额外的组)。