ICTSC2023 本戦 問題解説: [NBQ] 最小構成が好き
問題文
概要
家の押し入れに眠ってたオンボロPCを見つけた!
BIOSは起動したが、OSすら入ってなかったので適当な軽量OSのインストールをして起動して・・・よし起動した!
では早速環境構築だ。
私はタイプ精度が悪いのでコマンドでgrep と打ちたいときにgerpと打ってしまう癖がある。
そこで、gerpと打ってしまってもgrepが動くように設定したい。
リンクを張ってパスを通して・・・っとあれ?コマンドが見つからない?パスは通しているし、リンク先は存在するはずだぞ・・・
どうにか修正して gerp と打っても grep が起動するようにしてほしい。
あと、なぜ元の状態では動かないかも重ねて説明してほしい。
前提条件
- 報告書には初期状態では
gerpと打ってもgrepが動かない理由を簡潔に記すこと
初期状態
/usr/bin/grepに~/.bin/gerpを通じてシンボリックリンクが張られている~/.bin/gerpの$PATHは設定されているuserユーザーでログインしたとき、gerpと打ってもgrepが動かない
終了状態
userユーザーでログインしたとき、gerpと打ったらgrepが動く
解説
この問題では使用されているOSにも注目しながら解く必要があります。
uname -a などで確認すると、動いているOSが alpine-3 であることがわかります。
alpine-3 などの軽量OSでは標準コマンドのバイナリが busybox や coreutils といったバイナリに収納されています。
実際、grep も busybox によって動いていることを実機から確認できます。
では、このようなbusyboxなどはどのように指定されたバイナリを判別して動かしているのでしょうか。
今回の問題ではシンボリックリンクを用いておりますが、シンボリックリンクを用いた場合、実行時の引数 arg がその実行時の指定コマンドそのものになります。
(具体的な事例として、C言語などで int main(char** argv, int argc)などと書きますが、argv[0] には実行時のコマンドの名前が入ります。例えば、./a.outと実行すれば、argv[0] の値は "./a.out"です。)
busyboxなどはそのargを参照しながら実行するバイナリを決めています。
一方問題の環境ではgerpというシンボリックリンクを張っていました。
つまり、gerp と打てば busybox は gerp のバイナリを探しますが、存在しないので、missing applet などのエラーを出します。
では、gerp と打ってで grep を実行するにはどうすればよいか、となります。
今回の想定では、エイリアスを用いた解決となっておりました。
alias gerp=grep
などとすれば、gerp によって grep が動きます。これは、aliasは直前にコマンド文字列を置き換えるので、argの値はgrepとなります。
永続化は、ホームディレクトリのプロファイルに先程のコマンドを追加すると達成できます。
採点基準
- シェル起動時に
gerpと打てばgrepが動く状態である 100点(満点) - 以下減点
- 報告書に理由の記述が無い、不十分場合は 50点 減点
- 基準は、busybox の存在とその動作に関する言及があるかどうかである
- 報告書に理由の記述が無い、不十分場合は 50点 減点
講評
~/.bin/gerpをスクリプトとし、
#! /bin/bash
grep $@
などにする解答もありました。これも正解としました。
なお、 ~/.bashrc を追加しても 今回の環境においては動かないです。
すでに存在する ~/.profile を代わりに編集するのが一番楽だと思います。