grub2 配置中的命令“exec tail -n +3 $0”有什么逻辑?

Ima*_*jou 8 shell tail grub2 exec

创建自定义菜单项,卡在这个命令上:

exec tail -n +3 $0
Run Code Online (Sandbox Code Playgroud)

在终端中尝试过,得到了奇怪的结果,无法理解,这个命令究竟做了什么以及为什么 grub 需要它。请你解释一下好吗?

mur*_*uru 11

如果你在谈论/etc/grub.d/40_custom

$ cat /etc/grub.d/40_custom
#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries.  Simply type the
# menu entries you want to add after this comment.  Be careful not to change
# the 'exec tail' line above.
Run Code Online (Sandbox Code Playgroud)

然后注意:

  • 这是一个 shell 脚本,由它执行grub-mkconfig以构建 GRUB 配置
  • 这个文件应该是“一种添加自定义菜单条目的简单方法”——你只需输入你想要的任何 GRUB 配置。

但这是一个 shell 脚本,所以通常你必须做一些类似的事情echo "menuentry ...."。为了避免这种情况,使用了exec tail魔法。那有什么作用?$0,请记住,是执行时脚本的名称,因此通常是40_custom(或/etc/grub.d/40_custom等,具体取决于它的运行位置和方式)。所以脚本本质上是tail在自己运行,但是用-n +3, 告诉tail从第三行开始。

如果从第三行开始输出所有内容,你会得到什么/etc/grub.d/40_custom

# This file provides an easy way to add custom menu entries.  Simply type the
# menu entries you want to add after this comment.  Be careful not to change
# the 'exec tail' line above.
Run Code Online (Sandbox Code Playgroud)

(此外,您在此下方放置的其他任何内容。)

exec部分用 替换了正在执行脚本的外壳程序tail,因此实际上不会执行脚本之外的任何内容。


在终端中运行它:

  • $0可能是bash或类似的东西(可能是/bin/bash
  • 并且由于exec,您将正在运行的外壳替换为tail -n+3 bash
  • 并且由于您可能没有bash在当前目录中命名的文件,因此tail立即退出。

所以最终结果很可能是你的终端会话在那里结束。


ilk*_*chu 10

tail -n +3从第 3 行(手册页)开始打印其输入。$0是 shell 脚本中脚本的名称(Bash 特殊参数)并且execBash 内置函数)用命令替换脚本。你可能有这样的东西(比如在/etc/grub.d/40_custom我的系统中):

#!/bin/sh
exec tail -n +3 $0
foo
bar
Run Code Online (Sandbox Code Playgroud)

当您运行脚本时,它会通过tail读取脚本本身来替换自身,因此脚本的其余部分会被复制到其输出中。

我认为 grub 有一堆脚本来创建它的配置,它们可能会被执行grubscript.sh >> grub-config-file或起作用。脚本可以使用它们生成输出所需的任何逻辑,但该exec tail技巧允许只在输出中转储一些固定行,而无需更改脚本启动的逻辑。

除了那个神奇的咒语,Debian/etc/grub.d/40_custom还包括一条注释,告诉用户

只需在此评论后键入要添加的菜单条目。