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では標準コマンドのバイナリが busyboxcoreutils といったバイナリに収納されています。
実際、grepbusybox によって動いていることを実機から確認できます。

では、このようなbusyboxなどはどのように指定されたバイナリを判別して動かしているのでしょうか。
今回の問題ではシンボリックリンクを用いておりますが、シンボリックリンクを用いた場合、実行時の引数 arg がその実行時の指定コマンドそのものになります。
(具体的な事例として、C言語などで int main(char** argv, int argc)などと書きますが、argv[0] には実行時のコマンドの名前が入ります。例えば、./a.outと実行すれば、argv[0] の値は "./a.out"です。)
busyboxなどはそのargを参照しながら実行するバイナリを決めています。
一方問題の環境ではgerpというシンボリックリンクを張っていました。
つまり、gerp と打てば busyboxgerp のバイナリを探しますが、存在しないので、missing applet などのエラーを出します。

では、gerp と打ってで grep を実行するにはどうすればよいか、となります。
今回の想定では、エイリアスを用いた解決となっておりました。

alias gerp=grep

などとすれば、gerp によって grep が動きます。これは、aliasは直前にコマンド文字列を置き換えるので、argの値はgrepとなります。
永続化は、ホームディレクトリのプロファイルに先程のコマンドを追加すると達成できます。

採点基準

  • シェル起動時に gerp と打てば grep が動く状態である 100点(満点)
  • 以下減点
    • 報告書に理由の記述が無い、不十分場合は 50点 減点
      • 基準は、busybox の存在とその動作に関する言及があるかどうかである

講評

~/.bin/gerpをスクリプトとし、

#! /bin/bash

grep $@

などにする解答もありました。これも正解としました。

なお、 ~/.bashrc を追加しても 今回の環境においては動かないです。
すでに存在する ~/.profile を代わりに編集するのが一番楽だと思います。