0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Cで作る最小構成のシェル

0
Last updated at Posted at 2025-12-22

Linux で動く 最小限のシェル を C で実装しながら、

  • シェルがどうやってコマンドを実行しているのか
  • execvp は何をしているのか
  • $PATH はどう使われているのか
  • perror は何のためにあるのか

を整理していきます。


シェルの基本構造

Unix 系 OS のシェルは、基本的に次の流れで動いています。

  1. ユーザから 1 行入力を読む
  2. コマンドと引数に分解する
  3. fork() で子プロセスを作る
  4. 子プロセスで exec() して別のプログラムに置き換える
  5. 親プロセスは wait() で終了を待つ

最小構成のシェル実装例

以下は Linux 前提の、非常にシンプルなシェルです。

機能

  • プロンプト表示
  • コマンド実行
  • cd(ビルトイン)
  • exit(ビルトイン)

simple_shell.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>

#define MAX_LINE 1024
#define MAX_ARGS 64

void parse_line(char *line, char **argv) {
    int i = 0;
    char *token = strtok(line, " \t\n");

    while (token != NULL && i < MAX_ARGS - 1) {
        argv[i++] = token;
        token = strtok(NULL, " \t\n");
    }
    argv[i] = NULL;
}

int main() {
    char line[MAX_LINE];
    char *argv[MAX_ARGS];

    while (1) {
        printf("myshell> ");
        fflush(stdout);

        if (fgets(line, sizeof(line), stdin) == NULL) {
            printf("\n");
            break;
        }

        parse_line(line, argv);

        if (argv[0] == NULL) {
            continue;
        }

        /* exit */
        if (strcmp(argv[0], "exit") == 0) {
            break;
        }

        /* cd */
        if (strcmp(argv[0], "cd") == 0) {
            if (argv[1] == NULL) {
                fprintf(stderr, "cd: missing argument\n");
            } else if (chdir(argv[1]) != 0) {
                perror("cd");
            }
            continue;
        }

        pid_t pid = fork();
        if (pid == 0) {
            execvp(argv[0], argv);
            perror("execvp");
            exit(1);
        } else if (pid > 0) {
            int status;
            waitpid(pid, &status, 0);
        } else {
            perror("fork");
        }
    }

    return 0;
}

execvp とは何か?

int execvp(const char *file, char *const argv[]);

execvpは現在のプロセスを別のプログラムに置き換える関数です。

  • 成功すると 戻ってこない
  • 失敗したときだけ -1 を返す

$PATHは自動で検索される?

される。
execvppPATH検索を意味しています。

ただし、コマンド名に/が含まれている場合、その限りではありません(PATHからは検索されません)。

関数名 PATH検索 引数形式
execl 可変長
execv 配列
execvp 配列
execve 配列(env指定可)

実体は execve で、他はラッパーです。

perrorとは?

void perror(const char *s);
  • 直前に失敗したシステムコールの理由を表示
  • 内部で errno を参照
  • stderr に出力される
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?