我也在 stack overflow 上发布了这个问题。这里:https://stackoverflow.com/questions/55689120/identical-scripts-same-permissions-one-hangs-one-doesnt-how-why请在您认为最适合该问题的网站回答。这将帮助我了解我应该使用哪个网站。谢谢。
我总是忘记命令的名称inxi
,所以前段时间我创建了一个名为sysinfo-
(注意末尾的‘-’,以区分我的脚本和 Linux 命令 sysinfo。)
$ cat ~/scripts/sysinfo-
#!/bin/bash
# DESCRIPTION
#
# Display system info at the command promp
#
# Main Program
echo -e "#############\n# inxi -b #\n#############\n"
/usr/bin/inxi -b
echo -e "############"
当我升级系统并将 inxi 升级到版本 3.0.27 时,此脚本停止工作。当脚本到达 inxi 命令时会挂起,必须使用 CTRL+C 将其终止
inxi 的开发人员建议我将其升级到 3.0.33 版本,我照做了。不幸的是,升级并没有改变运行原始脚本的结果。然而,经过一些测试,我发现了一些无法解释的事情:我的脚本的精确副本可以成功运行,但原始脚本却无法运行!?
jesse@Limbo ~ $ ~/scripts/sysinfo-
#############
# inxi -b #
#############
^C
jesse@Limbo ~ $ cat ~/scripts/sysinfo- > /tmp/inxi.test
jesse@Limbo ~ $ chmod +x /tmp/inxi.test
jesse@Limbo ~ $ /tmp/inxi.test
#############
# inxi -b #
#############
System: Host: Limbo Kernel: 4.15.0-47-generic x86_64 bits: 64 Desktop: Cinnamon 4.0.10 Distro: Linux Mint 19 Tara
Machine: Type: Desktop System: MSI product: MS-7823 v: 1.0 serial: <root required>
Mobo: MSI model: CSM-H87M-G43 (MS-7823) v: 1.0 serial: <root required> BIOS: American Megatrends v: 1.6
date: 02/22/2014
CPU: Quad Core: Intel Core i7-4790 type: MT MCP speed: 3879 MHz min/max: 800/4000 MHz
Graphics: Device-1: NVIDIA GM107GL [Quadro K2200] driver: nvidia v: 390.116
Display: x11 server: X.Org 1.19.6 driver: nvidia unloaded: fbdev,modesetting,nouveau,vesa
resolution: 1920x1080~60Hz, 1280x1024~60Hz
OpenGL: renderer: Quadro K2200/PCIe/SSE2 v: 4.6.0 NVIDIA 390.116
Network: Device-1: Realtek RTL8111/8168/8411 PCI Express Gigabit Ethernet driver: r8169
Device-2: Realtek RTL8111/8168/8411 PCI Express Gigabit Ethernet driver: r8169
Drives: Local Storage: total: 14.44 TiB used: 8.32 TiB (57.7%)
Info: Processes: 316 Uptime: 56m Memory: 31.34 GiB used: 4.80 GiB (15.3%) Shell: inxi.test inxi: 3.0.33
############
jesse@Limbo ~ $ diff ~/scripts/sysinfo- /tmp/inxi.test
jesse@Limbo ~ $ ls -l ~/scripts/sysinfo- /tmp/inxi.test
-rwxr-x--- 1 jesse jesse 187 Apr 15 18:46 /home/jesse/scripts/sysinfo-
-rwxr-x--- 1 jesse jesse 187 Apr 15 19:09 /tmp/inxi.test
jesse@Limbo ~ $ md5sum ~/scripts/sysinfo- /tmp/inxi.test
a1356223d7bacb6d5b6d74cf44d733f2 /home/jesse/scripts/sysinfo-
a1356223d7bacb6d5b6d74cf44d733f2 /tmp/inxi.test
这怎么可能?
如果原始文件有某种损坏,diff 不会发现吗?我该如何检查?
是否有可能自动创建某种策略文件,因为我还没有创建,可以防止inxi
在脚本中运行~/scripts
??
太棒了!!
jesse@Limbo ~ $ mv /tmp/inxi.test ~/scripts/
jesse@Limbo ~ $ ~/scripts/inxi.test
#############
# inxi -b #
#############
^C
这可能是一种装甲政策吗?
jesse@Limbo ~ $ apparmor_status | grep inxi
没有结果。
我尝试过同时env
放置~/scripts/sysinfo-
/tmp/inxi.test
#!/bin/bash
# DESCRIPTION
#
# Display system info at the command promp
#
env
# Main Program
echo -e "#############\n# inxi -b #\n#############\n"
/usr/bin/inxi -b
echo -e "############"
env
但两个脚本的输出是相同的。
jesse@Limbo ~ $ diff ~/scripts/sysinfo- /tmp/inxi.test
jesse@Limbo ~ $ ~/scripts/sysinfo- > /tmp/sysinfo.output
^C
jesse@Limbo ~ $ /tmp/inxi.test > /tmp/inxi.test.output
jesse@Limbo ~ $ diff /tmp/sysinfo.output /tmp/inxi.test.output
61a62,75
> System: Host: Limbo Kernel: 4.15.0-47-generic x86_64 bits: 64 Desktop: Cinnamon 4.0.10 Distro: Linux Mint 19 Tara
> Machine: Type: Desktop System: MSI product: MS-7823 v: 1.0 serial: <root required>
> Mobo: MSI model: CSM-H87M-G43 (MS-7823) v: 1.0 serial: <root required> BIOS: American Megatrends v: 1.6
> date: 02/22/2014
> CPU: Quad Core: Intel Core i7-4790 type: MT MCP speed: 1355 MHz min/max: 800/4000 MHz
> Graphics: Device-1: NVIDIA GM107GL [Quadro K2200] driver: nvidia v: 390.116
> Display: x11 server: X.Org 1.19.6 driver: nvidia unloaded: fbdev,modesetting,nouveau,vesa
> resolution: 1920x1080~60Hz, 1280x1024~60Hz
> OpenGL: renderer: Quadro K2200/PCIe/SSE2 v: 4.6.0 NVIDIA 390.116
> Network: Device-1: Realtek RTL8111/8168/8411 PCI Express Gigabit Ethernet driver: r8169
> Device-2: Realtek RTL8111/8168/8411 PCI Express Gigabit Ethernet driver: r8169
> Drives: Local Storage: total: 14.44 TiB used: 8.32 TiB (57.7%)
> Info: Processes: 315 Uptime: 1h 40m Memory: 31.34 GiB used: 4.97 GiB (15.9%) Shell: inxi.test inxi: 3.0.33
> ############
正如您所看到的,问题不在于运行 bash 脚本~/scripts
,而在于inxi
运行~/scripts
~/scripts
恰好是我的系统上的绑定挂载目录。也许这就是问题所在?
答对了!!
jesse@Limbo ~ $ mv ~/scripts/sysinfo- ~/
jesse@Limbo ~ $ ~/sysinfo-
#############
# inxi -b #
#############
System: Host: Limbo Kernel: 4.15.0-47-generic x86_64 bits: 64 Desktop: Cinnamon 4.0.10 Distro: Linux Mint 19 Tara
Machine: Type: Desktop System: MSI product: MS-7823 v: 1.0 serial: <root required>
Mobo: MSI model: CSM-H87M-G43 (MS-7823) v: 1.0 serial: <root required> BIOS: American Megatrends v: 1.6
date: 02/22/2014
CPU: Quad Core: Intel Core i7-4790 type: MT MCP speed: 900 MHz min/max: 800/4000 MHz
Graphics: Device-1: NVIDIA GM107GL [Quadro K2200] driver: nvidia v: 390.116
Display: x11 server: X.Org 1.19.6 driver: nvidia unloaded: fbdev,modesetting,nouveau,vesa
resolution: 1920x1080~60Hz, 1280x1024~60Hz
OpenGL: renderer: Quadro K2200/PCIe/SSE2 v: 4.6.0 NVIDIA 390.116
Network: Device-1: Realtek RTL8111/8168/8411 PCI Express Gigabit Ethernet driver: r8169
Device-2: Realtek RTL8111/8168/8411 PCI Express Gigabit Ethernet driver: r8169
Drives: Local Storage: total: 14.44 TiB used: 8.33 TiB (57.7%)
Info: Processes: 322 Uptime: 1h 52m Memory: 31.34 GiB used: 5.36 GiB (17.1%) Shell: sysinfo- inxi: 3.0.33
############
但请稍等...
jesse@Limbo ~ $ mv ~/sysinfo- ~/scripts/
jesse@Limbo ~ $ cp ~/scripts/sysinfo- ~/
jesse@Limbo ~ $ chmod +x ~/sysinfo-
jesse@Limbo ~ $ ~/sysinfo-
#############
# inxi -b #
#############
^C
嗯???
我将脚本移回绑定挂载~/scripts
目录,然后将其复制(而不是移动)到~/
,使新文件可执行,然后......inxi
挂起!
这种行为肯定是来自某个策略,该策略能够区分移动的文件和复制的文件。程序从 bash 脚本中运行,而不是从命令行运行。除了 apparmor 之外,还有什么可以做到这一点??
jesse@Limbo ~ $ cd ~/scripts/
jesse@Limbo ~/scripts $ inxi -b
System: Host: Limbo Kernel: 4.15.0-47-generic x86_64 bits: 64 Desktop: Cinnamon 4.0.10 Distro: Linux Mint 19 Tara
Machine: Type: Desktop System: MSI product: MS-7823 v: 1.0 serial: <root required>
Mobo: MSI model: CSM-H87M-G43 (MS-7823) v: 1.0 serial: <root required> BIOS: American Megatrends v: 1.6
date: 02/22/2014
CPU: Quad Core: Intel Core i7-4790 type: MT MCP speed: 1500 MHz min/max: 800/4000 MHz
Graphics: Device-1: NVIDIA GM107GL [Quadro K2200] driver: nvidia v: 390.116
Display: x11 server: X.Org 1.19.6 driver: nvidia unloaded: fbdev,modesetting,nouveau,vesa
resolution: 1920x1080~60Hz, 1280x1024~60Hz
OpenGL: renderer: Quadro K2200/PCIe/SSE2 v: 4.6.0 NVIDIA 390.116
Network: Device-1: Realtek RTL8111/8168/8411 PCI Express Gigabit Ethernet driver: r8169
Device-2: Realtek RTL8111/8168/8411 PCI Express Gigabit Ethernet driver: r8169
Drives: Local Storage: total: 14.44 TiB used: 8.33 TiB (57.7%)
Info: Processes: 315 Uptime: 2h 01m Memory: 31.34 GiB used: 4.96 GiB (15.8%) Shell: bash inxi: 3.0.33
我看不出目录权限有什么影响
jesse@Limbo ~/scripts $ ls -ld /tmp/ ~/scripts/ ~/
drwxr-x--- 194 jesse jesse 20480 Apr 15 20:06 /home/jesse/
drwxrwx--- 18 jesse jesse 12288 Apr 15 20:06 /home/jesse/scripts/
drwxrwxrwt 20 root root 24576 Apr 15 20:32 /tmp/
答案1
有没有人发现 dmidecode、lshw、lspci、lsusb、lsblk 或 blkid 实用程序试图回调 parent_script?没有。实际上,任何 UNIX 或 Linux 实用程序都会回调 parent_script。没有。令人惊讶的是,较新的 inxi 版本确实如此。
inxi 开发人员认为,在不了解 parent_script 的情况下回调 parent_script 是完全正常的。常识是,除非您了解该脚本及其行为方式,否则永远不要回调 parent_script。您只是在要求恶性递归循环。如果恶性循环运行时间足够长,它可能会填满 Linux proc 表或耗尽所有可用内存。并且 inxi 开发人员使用非常糟糕的假设对 inxi 进行了根本性的更改,并创建了这种情况。
以前的 2.x 版 inxi 从未对 parent_script 执行回调。我可以想象许多用户或系统管理员一直在每月脚本中使用 inxi 实用程序来帮助记录他们的服务器。而且,使用 inxi 2.x 后,它对他们来说运行正常。
inxi 实用程序的 3.x 版本改变了基本行为。现在,inxi 将执行对 parent_script --version 的回调。inxi 开发人员假设 parent_script 将以同样的方式响应 --version 参数。当 2.x 版本的 inxi 基本行为没有这样做时,为什么有人会期望 --version 回调?这对于 cronjob 脚本来说可能非常糟糕。
3.x 版本有一个非常根本的变化,它会以恶性递归循环让许多用户措手不及。我试图让 inxi 开发人员解释他为什么要改变现有的基础行为,以及 parent_script --version 提供了什么有用的目的。祝你好运得到答案。
如何重现问题
在我的示例中,/home/temp/bin 目录位于我的 PATH 中。
将这个简单的“dltest”脚本放在你的一个 PATH 目录中,它将重现该问题:
# cat dltest
#!/bin/bash
# Open another terminal and use ps -ft /dev/pts/? to view the spawned process.
echo -e "\nUsing `tty`.\nSleeping yawn. Taking five seconds...\n" ; sleep 5
echo -e "\nStarting inxi -Ixxx\n"
# for a test use a very basic inxi.
/usr/bin/inxi -Ixxx
$ pwd
/home/temp/bin
$
$ ./dltest
Using /dev/pts/0.
Sleeping yawn. Taking five seconds...
Starting inxi_3.0.32
Concurrently using another terminal:
$ ps -ft pts/0
UID PID PPID C STIME TTY TIME CMD
temp 1820 1816 0 11:02 pts/0 00:00:00 bash
temp 13068 1820 0 14:28 pts/0 00:00:00 /bin/bash ./dltest
temp 13070 13068 0 14:28 pts/0 00:00:00 sleep 5
$ ps -ft pts/0
UID PID PPID C STIME TTY TIME CMD
temp 1820 1816 0 11:02 pts/0 00:00:00 bash
temp 13068 1820 0 14:28 pts/0 00:00:00 /bin/bash ./dltest
temp 13072 13068 18 14:29 pts/0 00:00:00 /usr/bin/perl /usr/bin/inxi
temp 13081 13072 0 14:29 pts/0 00:00:00 sh -c /home/temp/bin/dltest --version 2>/dev/null
temp 13082 13081 0 14:29 pts/0 00:00:00 /bin/bash /home/temp/bin/dltest --version
temp 13084 13082 0 14:29 pts/0 00:00:00 sleep 5
# The longer it runs the deeper it will get.
$ ps -ft pts/0
UID PID PPID C STIME TTY TIME CMD
temp 1820 1816 0 11:02 pts/0 00:00:00 bash
temp 13622 1820 0 14:48 pts/0 00:00:00 /bin/bash ./dltest
temp 13625 13622 1 14:48 pts/0 00:00:00 /usr/bin/perl /usr/bin/inxi -tty -Ixxx
temp 13634 13625 0 14:48 pts/0 00:00:00 sh -c /home/temp/bin/dltest --version 2>/dev/null
temp 13635 13634 0 14:48 pts/0 00:00:00 /bin/bash /home/temp/bin/dltest --version
temp 13638 13635 1 14:48 pts/0 00:00:00 /usr/bin/perl /usr/bin/inxi -tty -Ixxx
temp 13647 13638 0 14:48 pts/0 00:00:00 sh -c /home/temp/bin/dltest --version 2>/dev/null
temp 13648 13647 0 14:48 pts/0 00:00:00 /bin/bash /home/temp/bin/dltest --version
temp 13652 13648 2 14:48 pts/0 00:00:00 /usr/bin/perl /usr/bin/inxi -tty -Ixxx
temp 13661 13652 0 14:48 pts/0 00:00:00 sh -c /home/temp/bin/dltest --version 2>/dev/null
temp 13662 13661 0 14:48 pts/0 00:00:00 /bin/bash /home/temp/bin/dltest --version
temp 13665 13662 20 14:48 pts/0 00:00:00 /usr/bin/perl /usr/bin/inxi -tty -Ixxx
temp 13674 13665 0 14:48 pts/0 00:00:00 sh -c /home/temp/bin/dltest --version 2>/dev/null
temp 13675 13674 0 14:48 pts/0 00:00:00 /bin/bash /home/temp/bin/dltest --version
temp 13677 13675 0 14:48 pts/0 00:00:00 sleep 5
temp@lm19:~$
为了防止这种恶性循环,您可以在脚本顶部添加此解决方法。
if [[ "${1}" == "--version" ]] ; then
# work around for inxi_3.0.32 parent --version anomaly
exit 1
fi