
大学で以下のような課題を出されました。
・コマンドライン入力を受け付けて、実行可能ファイルを実行できる
コマンドサーチパスを持っている方が望ましいが、実行時に full path指定
するのでも構わない
・バックグラウンド実行
・標準入出力・エラー出力のリダイレクション
・パイプによる標準入出力の他プロセスへの接続
作成の上で条件は以下の通りです。
・使ってよいのは基本的にはシステムコールのみ
man で (2)
execve, fork, pipe, dup, read, write, open
・プログラム作成の効率化を考慮して以下の library関数は使うことを認める
exec周り execv
文字列関係 str...
入出力関係 fprintf, fgets
入出力関係は、コマンドライン入力、エラー出力に限る
今までshellを作成したことが無くどうすればよいか良く分かりません。
fork()やexec()の意味はなんとなくは理解したのですが・・・
No.2ベストアンサー
- 回答日時:
★まずはコマンドラインの入力処理を作成しましょう。
・簡単なアルゴリズム
(1)fgets() 関数で文字列を入力待ち状態にします。
(2)文字列が入力されたら、起動コマンド名とその引数に分割します。
(3)起動コマンド名にパスがなければ、環境変数 PATH などを参照してパスを探す。
(4)起動コマンド名が見つからなければエラー表示します。
(5)起動コマンド名が見つかれば、fork()、exec() で実行します。→バックグラウンドで実行させる。
(6)(1)へ戻り入力待ち状態を繰り返す。
上記の方法で簡単なコマンドライン・システムが組めます。
・リダイレクションは標準入出力を dup() 関数などで切り替えます。つまり、
入力リダイレクションでは標準入力をファイルから読み込むように stdin の属性を変更し、
出力リダイレクションでは標準出力をファイルに書き込むように stdout の属性を変更します。
・パイプ処理は標準出力を一時ファイルに出力するように加工します。出力リダイレクションの考えと
同じです。そして、一時ファイルに出力したファイルを標準入力に読み込むように加工します。
これは入力リダイレクションと同じ考えです。
このような仕組みの為、先に入出力リダイレクションの機能を作ります。
上手く実装できたらば、パイプ処理も意外に簡単に作れますよ。
サンプル:
char buff[ 256 ];
char *argv[ 256 ];
int argc;
while ( fgets(buff,sizeof(buff),stdin) != NULL ){ ←(1)入力待ち
argc = split( argv, buff ); ←(2)コマンド名と引数を分離
if ( (argv[0] = check(argv[0])) == NULL ){ ←(3)コマンド名の有無をチェック
printf( "エラー表示\n" ); ←(4)コマンド名が見つからないエラー
}
else{
execute( argv[0], argv + 1, argc - 1 ); ←(5)バックグラウンドで実行させる
}
free( argv[0] ); ←解放
}
解説:
・split() 関数は文字列 buff をコマンド名と引数に分離して argv のポインタ配列にセットします。
また、分離した個数をリターンします。分離するときはスペースで分離していきます。
・check() 関数ではコマンド名のパスをチェックしてない場合は環境変数 PATH などを参照して
パス名を探します。そして、見つかったらばパスを補充した文字列を malloc してリターンします。
なお、パスを補充しない文字列も malloc してからリターンします。
コマンド名が見つからない場合は NULL を返すようにします。
・execute() 関数の引数は、コマンド名、引数のポインタ配列、引数の個数です。
fork()、exec() 関数でプログラムをバックグラウンドで実行するようさせます。
・上記のサンプルには入出力リダイレクションの機能は記述されていません。
リダイレクションを実装するには <や>の語句を元に標準入出力をファイルに切り替える処理を
追加します。標準入出力は dup() 関数などを使います。この関数は標準入出力を切り替えるのに
とても重要な働きがあります。マニュアルなどをよく読み標準入出力を切り替えて下さい。
標準入出力の切り替えが出来たらば、execute() 関数を実行すれば良い。
・パイプ処理は入出力リダイレクションが出来れば、|文字の前の文字列で1つ実行したら、
その標準出力を出力リダイレクションと同じ考えて一時ファイルに出力します。
その後、一時ファイルを入力リダイレクションと同じ考えて stdin に切り替えます。
・以上。参考に。
No.4
- 回答日時:
なかなかの難問を出題されていますね。
参考文献として、絶版だと思いますが以下のものがあります。
・MS‐DOS用Shellの実現―Unix流シェルのプログラムと使い方 (単行本)
アレン ホルブ (著), 横山 和由 (翻訳)
amazonのマーケットプレイスにて購入可能です。私はこの本を参考に、まともなshellの無いOSにshellを導入しました。
それから、ちょっと反則技っぽいですが、linux上のc-shellやt-cshellのソースを参考にされるといいと思います。たったこれだけの機能を実現するのが、こんなに大変なの?っていう気分になります。
No.3
- 回答日時:
参考までに、私は参考の書籍を紹介したいと思います。
「UNIX Cプログラミング」という本です。
発行されてから結構経ちますが、この本はUNIXでシステムコールを扱う際に参考になります。
シェルやリダイレクト、パイプ処理なども掲載されています。
図書館などで軽く読んでみても、いいかもしれません。
課題頑張ってくださいね^^
参考URL:http://www.ascii.co.jp/books/books/detail/4-7561 …
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# プログラミングの問題です。至急教えてください。 /***から***/の部分をプログラミングにしてほし 1 2022/10/13 11:48
- Java java 次の機能を有するメソッドを自クラスに作成し、実装したいです。 機能 名前判定機能 →名前が 3 2022/06/16 16:08
- C言語・C++・C# 至急教えてください。プログラミングの問題です。 malloc関数を使ってください!お願いします! 最 1 2022/07/21 09:28
- Java java 飾子を付けること(public static・・・) ・コンソールへの出力処理はmainメ 2 2022/06/16 19:34
- C言語・C++・C# 至急教えてください。プログラミングの問題です。 最初に正の整数nの入力を受け付け、次に分数の分子と分 1 2022/07/19 17:03
- C言語・C++・C# 至急お願いします。プログラミングの問題です。 malloc 関数を使って教えてください。 入出力例1 3 2022/07/21 09:36
- C言語・C++・C# c言語の問題です 2 2023/07/21 10:51
- Java Java 年数計算 3 2023/01/28 10:52
- C言語・C++・C# 至急お願いします。プログラミングの問題です。 最初に正の整数nの入力を受け付け、次に分数の分子と分母 3 2022/07/19 17:09
- C言語・C++・C# C言語 3 2022/10/04 15:07
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
バッチファイル 文字列にスペ...
-
バッチ終了時にDOS窓を閉じるコ...
-
シェルの「:コマンドが見つか...
-
findstrでヒットした1行前の文...
-
バッチファイルについて教えて...
-
コマンドプロンプトをクリック...
-
ftpのタイムアウト指定
-
コンピュータ名をファイル名に...
-
openofficeではがき差し込み印刷
-
shellの作成
-
ftpコマンドを実行すると「425 ...
-
SSH接続でwindowsサーバのコマ...
-
VBSでDOSプロンプト
-
UNIXshellをWINDOWSバッチファ...
-
FTPコマンドを非表示にする
-
フォルダ、ファイル操作に最適...
-
コードからアクセス権限の変更
-
2つ目の「pause」は無効?
-
プログラムの追加をバッチファ...
-
C言語で、string.h conio.hを使...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
バッチファイル 文字列にスペ...
-
バッチ終了時にDOS窓を閉じるコ...
-
コマンドプロンプトをクリック...
-
make test って何をするための...
-
findstrでヒットした1行前の文...
-
シェルの「:コマンドが見つか...
-
ショートカットをデスクトップ...
-
ftpコマンドを実行すると「425 ...
-
バッチファイルを使ってテキス...
-
Pythonで単純にファイルを結合...
-
フォルダ、ファイル操作に最適...
-
シェルスクリプト内のcdで、カ...
-
コンピュータ名をファイル名に...
-
DOSコマンドに詳しい方、お知恵...
-
SSH接続でwindowsサーバのコマ...
-
FTPの連続実行でフリーズする
-
ftpコマンド出力結果の取得
-
バッチファイルについて教えて...
-
2つ目の「pause」は無効?
-
バッチファイルでのMACアドレス...
おすすめ情報