web-dev-qa-db-ja.com

grub2 configからのコマンド "exec tail -n +3 $ 0"にはどのようなロジックがありますか?

カスタムメニューエントリを作成しています。次のコマンドで行き詰まっています:

exec tail -n +3 $0

ターミナルで試してみましたが、奇妙な結果になり、理解できません。このコマンドが正確に何をするのか、なぜgrubがそれを必要とするのか理解できません。説明して頂けますか?

8
Imajou

tail -n +3は、入力を3行目から出力します( man page )。 $0はシェルスクリプト内のスクリプトの名前( Bashの特別なパラメーター )であり、execBash builtins )はスクリプトをコマンド。あなたはおそらくこのようなものを持っています(私のシステムの/etc/grub.d/40_customのように):

#!/bin/sh
exec tail -n +3 $0
foo
bar

スクリプトを実行すると、スクリプト自体がtailに置き換えられ、スクリプト自体が読み取られるため、スクリプトの残りの部分が出力にコピーされます。

Grubにはその設定を作成するためのスクリプトがたくさんあると思います。それらはおそらくgrubscript.sh >> grub-config-fileまたは何かを実行するために実行されます。スクリプトは、出力を生成するために必要な任意のロジックを使用できますが、exec tailトリックを使用すると、スクリプトの開始時のロジックを変更せずに、出力の固定行をダンプできます。

その魔法の呪文に加えて、Debianの/etc/grub.d/40_customには、ユーザーに

このコメントの後に追加するメニューエントリを入力するだけです。

10
ilkkachu

/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.

次に注意してください:

  • これはシェルスクリプトで、grub-mkconfigによって実行され、GRUB構成を構築します
  • このファイルは、「カスタムメニューエントリを追加する簡単な方法」であると想定されています。必要なGRUB構成を正確に入力するだけです。

ただし、これはシェルスクリプトであるため、通常はecho "menuentry ...."などのようにする必要があります。これを回避するには、exec tailマジックを使用します。それは何をしますか? $0は、実行されたスクリプトの名前であるため、通常は40_custom(または/etc/grub.d/40_customなど、実行された場所と方法によって異なります)です。そのため、スクリプトは基本的にtailをそれ自体で実行していますが、-n +3を使用してtailに3行目から開始するように指示しています。

/etc/grub.d/40_customの3行目以降をすべて出力すると何が得られますか?

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

(さらに、あなたがこれの下に置いた他のすべてのもの。)

exec部分は、スクリプトを実行しているシェルをtailに置き換えるため、スクリプトからそれ以上何も実行されません。


ターミナルで実行する:

  • $0はおそらくbashまたはそのようなものです(/bin/bashの場合もあります)。
  • execのため、実行中のシェルをtail -n+3 bashに置き換えます
  • 現在のディレクトリにbashという名前のファイルがない可能性があるため、tailはすぐに終了します。

したがって、最終結果は、ターミナルセッションがそこで終了した可能性があります。

11
muru