我试图执行UNIX cat“>”命令,从我的UNIX shell中执行file1.txt > foo.txt
。C Shell打开文件并返回到命令提示符
我想从用户输入中取得普通的UNIX命令,并通过execvp
执行它们(我现在做得很好)。
我要添加“>”到我的壳流,但我有与写它,并给代表团重新就业,为连续用户输入的指令行后关闭文件问题。有人可以向我解释我在做什么愚蠢的事情吗?我知道,为了写入文件,我必须关闭标准,打开一个新的标准,写入文件,然后以某种方式关闭文件的标准输出并重新启用键盘的标准输出以便能够接受用户再命令..
我的主要功能,只是给你一个想法:
int main(int argc, char **argv)
{
printf("[MYSHELL] $ ");
while (TRUE) {
user_input = getchar();
switch (user_input) {
case EOF:
exit(-1);
case '\n':
printf("[MYSHELL] $ ");
break;
default:
// parse input into cmd_argv - store # commands in cmd_argc
handle_user_input();
//determine input and execute foreground/background process
execute_command();
}
background = 0;
}
printf("\n[MYSHELL] $ ");
return 0;
}
这是我的函数获取用户输入的基础。如果它找到一个“>”的cmd_argv阵列中,它设置输出标志= 1和从期望的可执行命令删除它:
// get command line input
while ((user_input != '\n') && (buffer_characters < 50)) {
buffer[buffer_characters++] = user_input;
user_input = getchar();
}
// clear buffer
buffer[buffer_characters] = 0x00;
// populate cmd_argv - array of commands
char *buffer_pointer;
buffer_pointer = strtok(buffer, " ");
while (buffer_pointer != NULL) {
cmd_argv[cmd_argc] = buffer_pointer;
buffer_pointer = strtok(NULL, " ");
if(strcmp(cmd_argv[cmd_argc], ">") == 0){
cmd_argv[cmd_argc] = strtok(NULL, " ");
output = 1;
}
cmd_argc++;
if(output){
filename = buffer_pointer; //name of file that we're going to write to.
return;
}
}
的代码从execute_command驱动输出功能注意的I GOT这里味精。这似乎是在那里的死亡:
if (output == 1){
close(1);
file = fopen(filename, "w");
create_process();
output = 0;
printf("IT GOT HERE!!!\n");
fclose(file);
fopen("/dev/null", "r"); // open a new stdin that is always empty
return 1;
}else{
create_process();
return;
}
而且create_process处理前台和后台进程
void create_process()
{
status = 0;
int pid = fork();
background = 0;
if (pid == 0) {
// child process
if(background) {
printf("no background");
fclose(stdin); // close child's stdin
fopen("/dev/null", "r"); // open a new stdin that is always empty
execvp(*cmd_argv,cmd_argv);
// If an error occurs, print error and exit
fprintf (stderr, "unknown command: %s\n", cmd_argv[0]);
exit(1);
}else if(output == 1){
execvp(*cmd_argv,cmd_argv);
}
else {
execvp(*cmd_argv,cmd_argv);
// If an error occurs, print error and exit
fprintf (stderr, "unknown command: %s\n", cmd_argv[0]);
exit(1);
}
} else {
// parent process, waiting on child process
if (background) {
printf("starting background job %d\n", pid);
jobs_list[jobs_list_size] = pid;
jobs_list_size++;
} else {
waitpid(pid, &status, 0);
}
if (status != 0)
fprintf (stderr, "error: %s exited with status code %d\n", cmd_argv[0], status);
return;
}
}
感谢您的帮助! '不需要在父母中进行任何清理' - 你的意思是什么?我试过你的例子,并且认为它仍然需要用某种输出标志来包装,这取决于我的程序在调用create_process时的结构。思考? – user546459 2011-02-25 15:23:18
@ user546459:我的意思是说,因为你不曾打开父文件中的输出文件,或者改变父文件的打开文件,你以后也不必“修复它们”。使用你的程序结构,你必须将文件名传递给'create_process()',以便它可以在'fork()'之后执行'open()',所以你可以只有'filename == NULL'没有输出文件。 – caf 2011-02-25 23:56:26