読者です 読者をやめる 読者になる 読者になる

私をペロペロするがよい

lazy_dog のブログです。

systemd 時代の shutdown とか reboot コマンド

Linux

最近知った小ネタ。RHEL 7 を検証していた時に知ったことについて。systemd が入っている Linux では、どんな感じで shutdown コマンドとかを実行しているかについて。ちなみに、このエントリーは CentOS 7 の VM を使用して書いてる。

systemd 時代の shutdown コマンドは systemctl にエイリアスされてる

こんな感じ。

[root@localhost sbin]# cd /sbin
[root@localhost sbin]# ls -la | grep -i systemctl
lrwxrwxrwx.  1 root root          16 Jul 19 00:29 halt -> ../bin/systemctl
lrwxrwxrwx.  1 root root          16 Jul 19 00:29 poweroff -> ../bin/systemctl
lrwxrwxrwx.  1 root root          16 Jul 19 00:29 reboot -> ../bin/systemctl
lrwxrwxrwx.  1 root root          16 Jul 19 00:29 runlevel -> ../bin/systemctl
lrwxrwxrwx.  1 root root          16 Jul 19 00:29 shutdown -> ../bin/systemctl
lrwxrwxrwx.  1 root root          16 Jul 19 00:29 telinit -> ../bin/systemctl

はー、実質 systemctl が全部やってるんですね、と思ったのはいいものの、どんな風に処理されているのか気になった。

エイリアスのファイル名が引数となって systemctl が処理してるらしい

StackExchange から。ありがたやありがたや。

arch linux - Why are reboot, shutdown and poweroff symlinks to systemctl? - Unix & Linux Stack Exchange:
http://unix.stackexchange.com/questions/77029/why-are-reboot-shutdown-and-poweroff-symlinks-to-systemctl

There's typically a structure inside the program called a case/switch statement that determines the name the executable was called with and then will call the appropriate functionality for that executable name. That name is usually the first argument the program receives.

とのこと。要するに、シンボリックファイルのファイル名が引数として、systemctl が処理を変えている、らしい。

bash でそれっぽく検証

bash$0 で、自分自身のファイル名を取得できる。シンボリックリンクを張ったファイルでは、$0 がどんな形で表示できるか知りたくなったので、こんな感じで検証してみた。

[root@localhost work]# cat test.sh
#!/bin/bash

echo This file name is $0
[root@localhost work]#
[root@localhost work]# ln -s test.sh alias-01
[root@localhost work]#
[root@localhost work]# ls -la
total 8
drwxr-xr-x. 2 root root   35 Jul 19 01:09 .
dr-xr-x---. 3 root root 4096 Jul 19 01:07 ..
lrwxrwxrwx. 1 root root    7 Jul 19 01:09 alias-01 -> test.sh
-rw-r--r--. 1 root root   39 Jul 19 01:07 test.sh
[root@localhost work]#

ファイルを作った後、それぞれで実行してみる。

[root@localhost work]# sh test.sh
This file name is test.sh
[root@localhost work]#
[root@localhost work]# sh alias-01
This file name is alias-01
[root@localhost work]#

おー、シンボリックファイルのファイルを sh で実行したところ、エイリアスのファイル名が取れている。それを踏まえて、、、

[root@localhost work]# cat test2.sh
#!/bin/bash

$0
[root@localhost work]#
[root@localhost work]# ln -s test2.sh date
[root@localhost work]#
[root@localhost work]# ls -la
total 8
drwxr-xr-x. 2 root root   32 Jul 19 01:13 .
dr-xr-x---. 3 root root 4096 Jul 19 01:12 ..
lrwxrwxrwx. 1 root root    8 Jul 19 01:13 date -> test2.sh
-rw-r--r--. 1 root root   16 Jul 19 01:12 test2.sh
[root@localhost work]#
[root@localhost work]# sh date
Sat Jul 19 01:14:38 JST 2014
[root@localhost work]#

シンボリックファイルのファイル名のコマンドが実行できました。

じゃあ実際は?

C 読めないので本当かは分からんけど、多分? このへん? 多分。

https://github.com/systemd/systemd/blob/master/src/systemctl/systemctl.c#L6428-L6474