用C写一个简单的shell解释器,可以执行简单的命令并传递参数,实现管道的功能,其代码可以在window环境下运行的
时间: 2023-06-23 07:08:44 浏览: 85
以下是一个简单的shell解释器的代码,可在Windows环境下运行。它可以执行简单的命令并传递参数,还可以实现管道的功能。
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#define MAX_COMMAND_LENGTH 1024
#define MAX_ARGUMENTS 64
int main() {
char command[MAX_COMMAND_LENGTH];
char *arguments[MAX_ARGUMENTS];
char *token;
HANDLE hRead, hWrite;
SECURITY_ATTRIBUTES sa;
STARTUPINFO si;
PROCESS_INFORMATION pi;
BOOL success;
DWORD bytesRead;
char buffer[4096];
ZeroMemory(&sa, sizeof(sa));
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
while (1) {
printf("> ");
fgets(command, MAX_COMMAND_LENGTH, stdin);
if (strlen(command) == 1) {
continue;
}
command[strlen(command) - 1] = '\0';
token = strtok(command, " ");
int i = 0;
while (token != NULL) {
arguments[i++] = token;
token = strtok(NULL, " ");
}
arguments[i] = NULL;
if (strcmp(arguments[0], "exit") == 0) {
break;
}
if (strstr(command, "|") != NULL) {
char *leftCommand = strtok(command, "|");
char *rightCommand = strtok(NULL, "|");
CreatePipe(&hRead, &hWrite, &sa, 0);
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.hStdOutput = hWrite;
si.dwFlags |= STARTF_USESTDHANDLES;
ZeroMemory(&pi, sizeof(pi));
success = CreateProcess(NULL, leftCommand, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
if (!success) {
printf("Error: CreateProcess failed (%d).\n", GetLastError());
return 1;
}
CloseHandle(hWrite);
while (ReadFile(hRead, buffer, sizeof(buffer), &bytesRead, NULL) && bytesRead != 0) {
buffer[bytesRead] = '\0';
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.hStdInput = hRead;
si.dwFlags |= STARTF_USESTDHANDLES;
ZeroMemory(&pi, sizeof(pi));
success = CreateProcess(NULL, rightCommand, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
if (!success) {
printf("Error: CreateProcess failed (%d).\n", GetLastError());
return 1;
}
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
CloseHandle(hRead);
} else {
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
success = CreateProcess(NULL, command, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
if (!success) {
printf("Error: CreateProcess failed (%d).\n", GetLastError());
return 1;
}
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
}
return 0;
}
```
该代码采用了Windows API,使用了CreateProcess函数来启动子进程执行命令。如果输入的命令中包含管道符“|”,则使用CreatePipe函数创建一个匿名管道,将第一个命令的输出重定向到管道的写入端,然后将管道的读取端作为第二个命令的输入重定向。在执行完第二个命令后需要关闭管道的读取端和写入端。
注意,在Windows中要使用“\”而不是“/”来分隔路径。另外,如果要在命令中包含空格,需要用引号将命令括起来。
阅读全文