带间接输入的简单shell

时间:2014-11-06 16:11:11

标签: c bash shell

我正在编写一个简单的代码来实现unix / linux shell的间接输入函数。

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

extern void error(char* message);    
void
cisshRedirectedInput(char* command[], char* inputFile)
{
  //Try to implement the RedirectInput from here
    pid_t pid;
    int status;
    int fd;        
//For the child process
    if ((pid=fork())==0)
    {
        //Try to input files, failing on an error
    fd=open(inputFile,O_RDONLY);//To read input file

        if(fd < 0)
        {
            error("sampleSh: error opening standard input file");
            exit(1);
        }
        //use dup() to copy file
        close(1);
        if(dup(fd) < 0)
        {
            error("sampleSh: error duplicating standard input");
            perror("dup()");
            exit(1);
        }

        //Close file and exec()
        close(fd);
        execvp(command[0], command);
        //If failure in any case
        error("sampleSh: failure to execute command");
        exit(1);
    }          
    else
    {
        /* This is the parent process.
         * Wait for the child to terminate.
         */
        if(wait(&status) < 0)
        {
            error("sampleSh: error waiting for child.");
            perror("wait");
        }

        if(status != 0)
            error("sampleSh: command exited with nonzero error status.");
    }

}

然而,在编译之后(没有报告错误),但是当我尝试(已经创建了fileList)

sort -r <fileList

贝壳只是卡在那里而没有给我回答,请问有什么问题?

1 个答案:

答案 0 :(得分:2)

标准输入文件描述符为0(或STDIN_FILENO),而不是1(或STDOUT_FILENO)。

使用:

int fd = open(inputFile, O_RDONLY);

if (fd < 0) …
close(0);
if (dup(fd) < 0) …
close(fd);

或者:

int fd = open(inputFile, O_RDONLY);

if (fd < 0) …
if (dup2(fd, 0) < 0) …
close(fd);

在复制到标准I / O描述符后,您的代码执行close(fd)是很好的 - 这几乎总是正确的。检查关键系统调用是否成功也很好。 (如果close()失败,你可以做的很多。)


对代码进行简单修改(密钥更改:使用close(0);代替close(1);)对我有用。你有没有终止你的参数列表?

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

static inline void error(char *message)
{
    fprintf(stderr, "%s\n", message);
}

void
cisshRedirectedInput(char *command[], char *inputFile);

void
cisshRedirectedInput(char *command[], char *inputFile)
{
    // Try to implement the RedirectInput from here
    pid_t pid;
    int status;
    int fd;
    // For the child process
    if ((pid = fork()) == 0)
    {
        // Try to input files, failing on an error
        fd = open(inputFile, O_RDONLY); // To read input file

        if (fd < 0)
        {
            error("sampleSh: error opening standard input file");
            exit(1);
        }
        // use dup() to copy file
        close(0);
        if (dup(fd) < 0)
        {
            error("sampleSh: error duplicating standard input");
            perror("dup()");
            exit(1);
        }

        // Close file and exec()
        close(fd);
        execvp(command[0], command);
        // If failure in any case
        error("sampleSh: failure to execute command");
        exit(1);
    }
    else
    {
        /* This is the parent process.
         * Wait for the child to terminate.
         */
        if (wait(&status) < 0)
        {
            error("sampleSh: error waiting for child.");
            perror("wait");
        }

        if (status != 0)
            error("sampleSh: command exited with nonzero error status.");
    }
}

int main(void)
{
    char *args[] = { "sort", "-r", 0 };
    cisshRedirectedInput(args, "fileList");
    return 0;
}

输入文件:

bash-assoc-arrays.sh
cissh.c
fileList
kwargs.py
makefile
posixver.h
rangeinc.c
select.c
spc.py
testcsv.py
uncrustify.bug
yield.py

输出:

yield.py
uncrustify.bug
testcsv.py
spc.py
select.c
rangeinc.c
posixver.h
makefile
kwargs.py
fileList
cissh.c
bash-assoc-arrays.sh