相同的脚本,相同的权限,一个挂了,一个不挂,怎么回事?为什么?

相同的脚本,相同的权限,一个挂了,一个不挂,怎么回事?为什么?

我也在 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

相关内容