UnixやC言語の習得のため、

以下の記事にあった「シェルを実装する」という課題に
チャレンジしようと思っています。
http://slashdot.jp/articles/08/01/25/0318220.shtml

ただ、いままでC言語やUnixなどに深く関わってこなかったため、
何からやっていいかがいまいちピンと来ません。
参考になるような本やウェブサイトがあれば教えてください。

また、実装する指針を示してくれた方には
高ポイントをさし上げますので、そちらもお待ちしています。

よろしくお願いします。

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2008/02/03 10:18:37
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:tobeoscontinue No.5

回答回数220ベストアンサー獲得回数59

ポイント100pt

さすが東京大学、シェルを一ヶ月で作るという課題はすごいですねぇ。(私には無理)

解説PDFから必要な機能を列挙します。これらを一個一個解決していけばOKでしょう。


>•プロンプトを表示してユーザのコマンド入力を受け付ける.

>• 入力されたコマンドを解釈・実行する.

>• コマンドの実行が終わると再びプロンプトを表示する.

単純には下記のコードでも用件は満たしていると思います。

#include <stdio.h>

int main(int argc, const char *argv[])
{
  char command[4096];
  char* prompt = "$ ";

  while (1) {
    printf(prompt);
    fgets(command, 4096, stdin);
    /* ここでcommandを解釈して
       必要ならdup,pipeなどしてfokeで分身を作成し、
    execevで別のコマンドを実行させる */
  }
}

>• ジョブ管理(フォアグラウンド/バックグラウンド切り替え,

  ジョブの終了,サスペンド機能,etc…)を行う.

これらを実装するためにbash風のコマンドで書くと以下のコマンドを使えるようにする必要があります。

exit シェルを終了する。(子があればまずそれらを終了させる)

bg 現在のジョブまたはjobIDのジョブをバックグランドに設定

fg 現在のジョブまたはjobIDのジョブをフォアグランドに設定

kill ジョブを終了

suspend よくわからないorz

bg,fgは標準入出力、エラー(0,1,2)の切替えだけだと思いますが、もっとあるかも。


>• リダイレクト,パイプラインの機能を持つ.

bash風の記述では>、>>、|などを認識しなければなれません。

ジョブ管理もあるので&も認識する必要があります。


これらはbashでの記述ですのでシェルを作るわけですから違うようにしてもいいでしょう。

リダイレクトの記述はもっとわかりやすい記述が出来ないものかなぁとは思いますが。


リダイレクトはdupを使えば可能です。

パイプはpipeとdupを使い、更にforkしてexecevする感じになると思います。

私はISBN:4871481840

にある図を見てようやく納得がいきました(文章だけではイメージが湧かない)。


大枠ではこんな感じだとは思いますが、実際に実装するとなると結構大変だと思います。

処理対象は文字列なので特別な知識は必要ないのですが、あまり使わない、dup,pipe,fork,execevなどの動作を理解する必要があり、かなり深くOSを理解する必要があると思います。


UNIXの1/4世紀 (Ascii books)

にシェルはラインプリンター用紙7枚に収まった。とありますので400行(多分mainだけ?)程度でしょう。

またパイプの実装は長くかかったようでようやく|に落ち着いたようです。

(こちらの本は歴史的なもので技術的なものではありません)

id:kanouk

具体例をありがとうございます。

とても参考になりました。

2008/02/03 10:17:53

その他の回答4件)

id:uehaj No.1

回答回数158ベストアンサー獲得回数15

ポイント20pt

古典になってしまうかもしれませんが、以下の本が王道だと思います。

http://www.amazon.co.jp/UNIX%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9...

http://www.cbook24.com/bm_detail.asp?sku=99900499

「UNIXプログラミング環境」

id:kanouk

ありがとうございます。

読んでみます。

2008/02/03 10:15:30
id:KUROX No.2

回答回数3542ベストアンサー獲得回数140

ポイント20pt

UNIX Cプログラミング

David A.Curry著/アスキー書籍編集部監訳

http://www.ascii.co.jp/books/books/detail/4-7561-0078-3.shtml

-------

1.1 システムコールvsライブラリルーチン

2章 標準入出力ライブラリ

9章 プログラムの実行

10章 ジョブ制御

このあたりを読めばどうですかね。

シェルというより、要求を満たすCのプログラムを書けば課題は終了で、

実現にあたっては、bashとかの機能を使わないというだけの話だと思います。

id:kanouk

詳しく教えていただき、ありがとうございます。

是非読んでみたいと思います。

2008/02/03 10:15:58
id:ffmpeg No.3

回答回数1202ベストアンサー獲得回数9

ポイント10pt

UNIXを理解するには、やはり自分のPCにLinuxを入れていじるのが基本です。

できれば、すでにちゃんとうごいているSunのシステムとかを経験して、

それと同じシステムを、自分のPCに再現するという作業が第一歩です。

パーソナルユースでとっつきやすいのは、やはりvinelinuxで、

これのフリー版が付属している書籍を買うのが近道でしょう。

id:kanouk

こちらは勉強法についてですね。

私も同じように思います。

2008/02/03 10:16:50
id:wasisan No.4

回答回数86ベストアンサー獲得回数7

ポイント20pt

もうすでに上で出ている気がしますが.

Amazon.co.jp: Linuxプログラミング―例題で学ぶUNIXプログラミング環境のすべて: 本: ニール マシュー,リチャード ストーンズ,Neil Matthew,Richard Stones,葛西 重夫

が傑作だと思いました.実際にLinuxをインストールしてこの本の通読・コードを実行

していけばシェルに必要な知識の大部分を得ることが出来ると思います.

あと,「シェル」というのは結局のところ,PerlやRubyなどのスクリプト言語と

同じもの(bash, tcshなど)なので,

高度なものを作ろうと思えば,言語処理系の知識も求められますね.

Amazon.co.jp: プログラミング言語処理系 (岩波講座 ソフトウェア科学): 本: 佐々 政孝

が名著です.

id:kanouk

よく本屋さんで見る本ですが、中身までは確認していなかったです。

とても参考になりました。

2008/02/03 10:17:29
id:tobeoscontinue No.5

回答回数220ベストアンサー獲得回数59ここでベストアンサー

ポイント100pt

さすが東京大学、シェルを一ヶ月で作るという課題はすごいですねぇ。(私には無理)

解説PDFから必要な機能を列挙します。これらを一個一個解決していけばOKでしょう。


>•プロンプトを表示してユーザのコマンド入力を受け付ける.

>• 入力されたコマンドを解釈・実行する.

>• コマンドの実行が終わると再びプロンプトを表示する.

単純には下記のコードでも用件は満たしていると思います。

#include <stdio.h>

int main(int argc, const char *argv[])
{
  char command[4096];
  char* prompt = "$ ";

  while (1) {
    printf(prompt);
    fgets(command, 4096, stdin);
    /* ここでcommandを解釈して
       必要ならdup,pipeなどしてfokeで分身を作成し、
    execevで別のコマンドを実行させる */
  }
}

>• ジョブ管理(フォアグラウンド/バックグラウンド切り替え,

  ジョブの終了,サスペンド機能,etc…)を行う.

これらを実装するためにbash風のコマンドで書くと以下のコマンドを使えるようにする必要があります。

exit シェルを終了する。(子があればまずそれらを終了させる)

bg 現在のジョブまたはjobIDのジョブをバックグランドに設定

fg 現在のジョブまたはjobIDのジョブをフォアグランドに設定

kill ジョブを終了

suspend よくわからないorz

bg,fgは標準入出力、エラー(0,1,2)の切替えだけだと思いますが、もっとあるかも。


>• リダイレクト,パイプラインの機能を持つ.

bash風の記述では>、>>、|などを認識しなければなれません。

ジョブ管理もあるので&も認識する必要があります。


これらはbashでの記述ですのでシェルを作るわけですから違うようにしてもいいでしょう。

リダイレクトの記述はもっとわかりやすい記述が出来ないものかなぁとは思いますが。


リダイレクトはdupを使えば可能です。

パイプはpipeとdupを使い、更にforkしてexecevする感じになると思います。

私はISBN:4871481840

にある図を見てようやく納得がいきました(文章だけではイメージが湧かない)。


大枠ではこんな感じだとは思いますが、実際に実装するとなると結構大変だと思います。

処理対象は文字列なので特別な知識は必要ないのですが、あまり使わない、dup,pipe,fork,execevなどの動作を理解する必要があり、かなり深くOSを理解する必要があると思います。


UNIXの1/4世紀 (Ascii books)

にシェルはラインプリンター用紙7枚に収まった。とありますので400行(多分mainだけ?)程度でしょう。

またパイプの実装は長くかかったようでようやく|に落ち着いたようです。

(こちらの本は歴史的なもので技術的なものではありません)

id:kanouk

具体例をありがとうございます。

とても参考になりました。

2008/02/03 10:17:53
  • id:Kumappus
    まず実際にUnixいじってみて「シェルってどんなもの?」ってのを把握してからにしないとダメなんじゃないだろうか?
    あるいは、Windowsのcmd.exeも低機能ながら「シェル」なんで、バッチ処理のところを実装してみるとか。案外と奥が深いので>cmd.exe。

    シェルがやってることはユーザの打ち込んだ文字列を解析して、プログラムを起動すること、というのが一番基本で、さらにそこに例えば「繰り返し処理を簡潔に書くためのプログラムみたいなのが書ける」とか「出力先をいろいろ切り替えることができる」とか「そういうプログラムをテキストから読み込んで実行できる」とかそういう機能を足していったものと思えばだいたいあってます。

    だから、「文字列処理」「インタープリタ」「アプリを起動する仕掛け」あたりを勉強する必要があります。
  • id:wasisan
    すみません,上のLinuxプログラミング本は1版へのリンクでした.
    新しい2版はこちらです.

    http://www.amazon.co.jp/Linux%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E2%80%95%E4%BE%8B%E9%A1%8C%E3%81%A7%E5%AD%A6%E3%81%B6UNIX%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E7%92%B0%E5%A2%83%E3%81%AE%E3%81%99%E3%81%B9%E3%81%A6-%E3%83%8B%E3%83%BC%E3%83%AB-%E3%83%9E%E3%82%B7%E3%83%A5%E3%83%BC/dp/4797327014/ref=pd_sbs_b_title_1

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません