私は C で UNIX ミニシェルを書いていて、コマンド展開を追加している段階です。これが意味することは、コマンドを他のコマンドにネストできるということです。たとえば、次のようになります。
$> echo hello $(echo world! ... $(echo and stuff))
hello world! ... and stuff
私はそれがほとんど機能していると思いますが、展開された文字列の末尾を正しくマークしていません。たとえば、次の場合です。
$> echo a $(echo b $(echo c))
a b c
$> echo d $(echo e)
d e c
私が頼んだわけではありませんが、c が出力されるのを見てください。これが私のコードです:
msh.c - http://pastebin.com/sd6DZYwB expand.c - http://pastebin.com/uLqvFGPw
もっとコードがありますが、たくさんあります。これらは、現時点で問題を抱えている部分です。私がこれを行っている基本的な方法をお伝えしようと思います。
Main は msh.c にあります。ここでは、コマンドラインまたはシェルファイルから入力行を取得し、プロセスライン (char *line, int outFD, int waitFlag) を呼び出します。ここで、line は取得した行、outFD は出力ファイルのファイル記述子であり、waitFlag はフォークする場合に待機する必要があるかどうかを示します。これを main から呼び出すときは、次のようにします。
processline (buffer, 1, 1);
processline では、新しい行を割り当てます。
char expanded_line[EXPANDEDLEN];
次に、expand.c で expand を呼び出します。
expand(line, expanded_line, EXPANDEDLEN);
expand では、$( が見つかるまで文字列を line から Expanded_line に文字どおりにコピーし、次を呼び出します。
static int expCmdOutput(char *orig, char *new, int *oldl_ind, int *newl_ind)
orig は行、new は展開された行です。oldl_ind と newl_ind は、それぞれ行と展開された行の現在の位置です。次に、パイプを使用して processline を再帰的に呼び出し、ネストされたコマンドを渡します (たとえば、"echo a $(echo b)" がある場合は、processline "echo b" を渡します)。
これは私が混乱するところです.expandが呼び出されるたびに、EXPANDEDLEN longの新しいメモリチャンクが割り当てられますか? もしそうなら、これは悪いことです (非常にネストされたコマンドライン入力の場合)。expand では、展開された文字列の最後に null 文字を挿入します。なぜそれを超えて印刷されるのですか?
さらにコードや説明が必要な場合は、お尋ねください。第二に、大量のコードがあるため、コードをペーストビンに入れました。私の経験では、コードでいくつかのページを埋めると、人々はそれを気に入りません。