fileコマンドを使ってシェルスクリプトを探す

課題

PATHに含まれるディレクトリの中にあるコマンドで、現実にいくつのコマンドがシェルスクリプトなのか確かめよ。この作業自体を、一つのコマンド行で実行できるだろうか。

ですが、私(一井)はどうやったか?結論から言うと
$ for i in `echo $PATH | tr : '\012'` ; do file $i/* ; done | grep 'shell script' | wc -l
ですが、こんなものを一度に書き下せる訳がありません。少しずつ確かめながら実行していきます。

まず、
$ echo $PATH
/bin:/usr/bin:...
を行って、PATHの中身がどのように表示されるかを見ます。すると、ディレクトリ名が:でつながっていることが分かります。そこで、:を改行に置き換えて分解します。(空白に置き換えてもできる。)置き換えにはtrが使えます。

trの書式は以前やったので復習しておいてください。
「改行」はそのままでは入力・表示できないので、8進表現します。

問 改行(new line)のASCIIコードを調べよ。ヒント: $ man ascii

trで分解した後、forループを使って一つ一つ調べていくことにします。

forループを使うとき、対話的には
$ for i in `echo $PATH | tr : '\012'`
>
のように、途中で改行すると> というプロンプトが出るので、コマンドを順次入力していくことができます。"done"まで入力して試した後、bashのヒストリ機能を使ってもう一度呼び出してやると、一行になって出てきます。

fileコマンドは引数にファイル名をとるので、PATHに含まれるディレクトリ名の末尾に/*をくっつけてやればそのディレクトリ内のファイル全ての意味になることを考え、forループ内で実行します。

最後に、シェルスクリプトに対してfileコマンドは
$ file /usr/bin/nroff
/usr/bin/nroff: POSIX shell script, ASCII text executable
$ file /usr/bin/xrotate
/usr/bin/xrotate: Bourne-Again shell script, ASCII text executable
といった出力を出すので、'shell script'という文字列を含む行だけをgrepで抜き出し、結果をwcで数えれば出来上がりです。
  • Bourne-Again shellというのは、bashのことです。(なぜBorn-Againでない?)
  • POSIX shellというのは、IEEE(米国電気電子学会)で標準化されたUnixの規格に含められているシェルのことで、ここでは/bin/shをさします。

もっといい方法があるかもしれませんので、各自考えてみてください。

Comments