Я пытаюсь реализовать команду UNIX cat ">", чтобы выполнить file1.txt > foo.txt
из моей оболочки UNIX.
Я хочу взять обычные команды UNIX из пользовательского ввода и выполнить их через execvp
(что я сейчас делаю просто отлично).
Я хочу добавить ">" в мой поток оболочки , но у меня проблемы с закрытием файла после записи в него И возвращением делегирования в командную строку для постоянного пользователяinput. Может ли кто-нибудь объяснить мне, где я делаю что-то глупое?
Я понимаю, что для записи в файл мне нужно закрыть стандарт, открыть новый стандарт, написатьфайл, а затем каким-то образом закройте стандартный вывод файла и снова включите стандартный вывод клавиатуры, чтобы иметь возможность снова принимать пользовательские команды ..
Моя основная функция, просто чтобы дать вам представление:
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, управляющий выводомфункциональность Обратите внимание, я получил здесь MSG.Кажется, это где он умирает :
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;
}
}