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
を代わりに編集するのが一番楽だと思います。