linux - 相同的脚本,相同的权限,一个挂一个不挂,如何?为什么?

标签 linux bash

我还在 super 用户上发布了这个问题,此处:https://superuser.com/questions/1425657/identical-scripts-same-permissions-one-hangs-one-doesnt-how-why 。请在您认为最适合该问题的网站上回答。这将帮助我了解应该使用哪个网站。谢谢。

我总是忘记 inxi 命令的名称,所以前段时间我创建了一个名为 sysinfo- 的 bash 脚本(注意末尾的“-”将我的脚本与 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 中的脚本中运行??

BIGO!!

jesse@Limbo ~ $ mv /tmp/inxi.test ~/scripts/
jesse@Limbo ~ $ ~/scripts/inxi.test 
#############
#  inxi -b  #
#############

^C

这可能是一项 apparmor 政策吗?

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 
> ############

如您所见,问题不是从 ~/scripts 运行 bash 脚本的问题,而只是从 ~/scripts< 中的脚本运行 inxi 的问题。/

~/scripts 恰好是我系统上的绑定(bind)安装目录。也许这就是问题所在?

宾果!!

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

嗯???

我将脚本移回绑定(bind)安装的 ~/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/

最佳答案

有没有人发现 dmidecode、lshw、lspci、lsusb、lsblk 或 blkid 实用程序试图回调parent_script?不可以。就此而言,任何 UNIX 或 Linux 实用程序都会回调parent_script。不。惊喜,惊喜,惊喜,新的 inxi 版本确实如此。

inxi 开发人员认为,在对parent_script 没有任何深入了解的情况下对parent_script 进行回调是完全正常的。常识是永远不要对parent_script进行回调,除非您了解该脚本及其行为方式。你只是要求一个恶性递归循环。如果恶性循环运行足够长的时间,它可能会填满 Linux 进程表或耗尽所有可用内存。 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

关于linux - 相同的脚本,相同的权限,一个挂一个不挂,如何?为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55689120/

相关文章:

python - 从 VIM 中执行 Python 代码时如何抑制警告

linux - 为什么 echo `cat file` 会丢失所有格式?

linux - 从脚本执行命令时没有此类文件或目录错误

linux - 防止 usbhid 声明设备

linux - shmget() 返回的 shmid 是否跨进程唯一?

linux - 如何通过AT + CMGS发送短信?

python shutil.move : odd softlinking

bash - 如何通过 SSH 自动向多台服务器并行运行命令?

linux - 无法读取 bash 脚本

bash - 循环遍历除某些文件之外的文件的脚本