/etc/inittabの内容をレベル毎にソートして表示する


## 概要

/etc/inittab の内容をレベルごとにソートして表示する awk プログラム.

2021.09 時点では /etc/inittab は (ほぼ)使われていないだろうが、
次の awk 処理は活用できると思うので書き残しておく.

・awk から Linux コマンドを呼び出す処理
・awk から ファイルに書き出す処理
・行頭「#」の読み飛ばし処理
・空行の読み飛ばし処理
・スペース、タブのみの空白行の読み飛ばし処理



## 処理内容

左図が /etc/inittab の内容で、レベル(Lv) ごとに並び替えたものが右図である.
下図は Lv2 と Lv3 が並び替えられていることを記している.

並び替えに使うフィールドは、「:」を区切りとした第2フィールドである.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1246056/c51c1c49-d299-63c4-4d38-ab4b34f0323c.png)




## コード

ランレベルごとの情報はバッファではなくて、
一時ファイル「/tmp/(ランダム).(レベル)」というファイルに書き出す.

処理の最後に「/tmp/(ランダム).(レベル)」をダンプしている.

```bash
#!/bin/sh

test   -z "$1" && echo "Usage: `basename $0` inittab"    && exit 2
test ! -f "$1" && echo "Error: $1 was not found"         && exit 2

TMPF_R0=`mktemp --suffix=".0" -p /tmp`  # ランレベルなしの処理を書き出す
TMPF_R1=`mktemp --suffix=".1" -p /tmp`  # ランレベル 1 の処理を書き出す
TMPF_R2=`mktemp --suffix=".2" -p /tmp`  # ランレベル 2 の処理を書き出す
TMPF_R3=`mktemp --suffix=".3" -p /tmp`  # ランレベル 3 の処理を書き出す
TMPF_R4=`mktemp --suffix=".4" -p /tmp`  # ランレベル 4 の処理を書き出す
TMPF_R5=`mktemp --suffix=".5" -p /tmp`  # ランレベル 5 の処理を書き出す
TMPF_R6=`mktemp --suffix=".6" -p /tmp`  # ランレベル 6 の処理を書き出す

awk -v "OF0=$TMPF_R0"   \
    -v "OF1=$TMPF_R1"   \
    -v "OF2=$TMPF_R2"   \
    -v "OF3=$TMPF_R3"   \
    -v "OF4=$TMPF_R4"   \
    -v "OF5=$TMPF_R5"   \
    -v "OF6=$TMPF_R6"   \
'BEGIN {
    FS=":"                      # 区切り文字を「:」にする
    for( r = 0; r < 7; r++ ) {  # ランレベル判定処理に使う
        RUN_LEVELS[r] = r
    }
    ofile[0] = OF0
    ofile[1] = OF1
    ofile[2] = OF2
    ofile[3] = OF3
    ofile[4] = OF4
    ofile[5] = OF5
    ofile[6] = OF6
}
/^#/       { next }     # 行頭 # は読み飛ばす
/^$/       { next }     # 空行は読み飛ばす
/^[ \t]+$/ { next }     # 空白のみの行も読み飛ばす (「+」は1回以上の出現)
{
    for( i = 1; i < length(RUN_LEVELS); i++ ) {
        if ( $2 ~ RUN_LEVELS[i] ) {  #正規表現一致「~」で判定する。(完全一致「==」では無い)
            print $0 >> ofile[i]
        }
    }
    if( $2 == "" ) {    # フィールドが存在しない場合 (「==」による完全一致判定をする)
        print $0 >> ofile[0]
    }
}
END {
    # ランレベル単位で、一時ファイルに書き溜めた内容をダンプしていく
    for( i = 0; i < length(RUN_LEVELS); i++ ) {
        # ファイルをダンプするための Linux コマンドを組み立てる
        cmd = sprintf("test -f %s && cat %s", ofile[i], ofile[i])
        gsub(/0/, "NONE", i)
        printf("----------- %s ------------\n", i)
        # 組み立てた Linux コマンドを実行する
        system(cmd)
    }
}' $1
```

## 実行結果

/etc/inittab の内容は [後述](#/etc/inittab) している

```bash
$ sort_inittab.sh /etc/inittab
----------- NONE ------------
si::sysinit:/etc/rc.d/bcheckrc
ca::ctrlaltdel:/sbin/shutdown -t5 -rf now
----------- 1 ------------
l1:1:wait:/etc/rc.d/rc.single
----------- 2 ------------
id:2:initdefault:
l2:2345:wait:/etc/rc.d/rc.multi
1:23:respawn:/sbin/getty tty1 VC linux
2:23:respawn:/sbin/getty tty2 VC linux
3:23:respawn:/sbin/getty tty3 VC linux
4:23:respawn:/sbin/getty tty4 VC linux
----------- 3 ------------
l2:2345:wait:/etc/rc.d/rc.multi
1:23:respawn:/sbin/getty tty1 VC linux
2:23:respawn:/sbin/getty tty2 VC linux
3:23:respawn:/sbin/getty tty3 VC linux
4:23:respawn:/sbin/getty tty4 VC linux
S2:3:respawn:/sbin/uugetty ttyS2 M19200
----------- 4 ------------
l2:2345:wait:/etc/rc.d/rc.multi
----------- 5 ------------
l2:2345:wait:/etc/rc.d/rc.multi
----------- 6 ------------
l6:6:wait:/etc/rc.d/rc.reboot
```


## /etc/inittab

入力ファイルである.　なお、本ファイルは [man5/inittab.5.html] (https://man.plustar.jp/manpage/man5/inittab.5.html) を流用した.

```
# ブート後に入るべきランレベル
id:2:initdefault:

# 何より先ずシステムの初期化をする。
si::sysinit:/etc/rc.d/bcheckrc

# ランレベル0及び6はそれぞれ haltとreboot。
# 1 はメンテナンスモード
l0:0:wait:/etc/rc.d/rc.halt
l1:1:wait:/etc/rc.d/rc.single
l2:2345:wait:/etc/rc.d/rc.multi
l6:6:wait:/etc/rc.d/rc.reboot

# "三つ指をついてリセット"された時に何をすべきか。
ca::ctrlaltdel:/sbin/shutdown -t5 -rf now

# ランレベル2及び3: コンソールでgettyを実行する
# (レベル3の場合はモデムポートでも)。
1:23:respawn:/sbin/getty tty1 VC linux
2:23:respawn:/sbin/getty tty2 VC linux
3:23:respawn:/sbin/getty tty3 VC linux
4:23:respawn:/sbin/getty tty4 VC linux
S2:3:respawn:/sbin/uugetty ttyS2 M19200
```

以上.