我实际上在做自己的shell。
我做了以下特殊字符:
int commande(int fin, int fout, char * com, char * param, int * bg){
// execute a command
(ex. ls –l)
int symbole;
char *mot;
pid_t pid;
symbole = parsing();
switch(symbole){
case 0: // NL
case 1: // ;
case 2: // &
case 3: // <
case 4: // >
case 5: // | (Here I have some issues when I try to redirect the output of a command).
(correspond à ctrl+D)
case 10:// Mot
default:
}
return;
}
但是当我有两个跟随自己的指令时,我有一些问题要在输出管道时重定向输出“|”。事实上,我已经尝试了以下有效的操作:
>myShell ps > fich
>myShell ls -l | wc -l
但不是这一个:
>myShell ls -l | wc -l >file
这里是专门开发的两个案例。我认为问题出现在案例5而不是案例4中,因为我尝试过的第一个命令(我在上面给你看过)。
case 4: // SYMBOLE : >
if(output==0){
output=1;
execute=1;
for (l=0;l<10;l++){
eltsoutput[l]=eltsCommande[l];
}
}
break;
case 5: // SYMBOLE : |
//if(tube==0){
/*for (l=0;l<10;l++){
eltstube[l]=eltsCommande[l];
}*/
p2=fork();
if(p2==0){
if(tube==0){
freopen( "fichtmp", "w", stdout );
execvp(eltsCommande[0], eltsCommande);
}
return(0);
}
else{ if(background==0){ // SANS MOD BG ATTENDRE FIN FILS
waitpid(p2, NULL, 0);
}
tube=1;
execute=1;
}
break;
你能帮我找到一种方法,用|同时执行两个命令并允许他们的结果转到文件?
在我的shell中,案例是在使用指令“;”重定向的情况下工作:
}else if(output==1){
close(1);
int filew = creat(eltsCommande[0], 0644);
execvp(eltsoutput[0], eltsoutput);
也许我应该使用这段代码来实现它?
答案 0 :(得分:1)
查看NetBSD /bin/sh source code,我看到以下管道实现:
static int
sh_pipe(int fds[2])
{
int nfd;
if (pipe(fds))
return -1;
if (fds[0] < 3) {
nfd = fcntl(fds[0], F_DUPFD, 3);
if (nfd != -1) {
close(fds[0]);
fds[0] = nfd;
}
}
if (fds[1] < 3) {
nfd = fcntl(fds[1], F_DUPFD, 3);
if (nfd != -1) {
close(fds[1]);
fds[1] = nfd;
}
}
return 0;
}
evalpipe使用2个文件描述符调用此函数:
STATIC void
evalpipe(union node *n)
{
struct job *jp;
struct nodelist *lp;
int pipelen;
int prevfd;
int pip[2];
TRACE(("evalpipe(0x%lx) called\n", (long)n));
pipelen = 0;
for (lp = n->npipe.cmdlist ; lp ; lp = lp->next)
pipelen++;
INTOFF;
jp = makejob(n, pipelen);
prevfd = -1;
for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
prehash(lp->n);
pip[1] = -1;
if (lp->next) {
if (sh_pipe(pip) < 0) {
if (prevfd >= 0)
close(prevfd);
error("Pipe call failed");
}
}
if (forkshell(jp, lp->n, n->npipe.backgnd ? FORK_BG : FORK_FG) == 0) {
INTON;
if (prevfd > 0) {
close(0);
copyfd(prevfd, 0, 1);
close(prevfd);
}
if (pip[1] >= 0) {
close(pip[0]);
if (pip[1] != 1) {
close(1);
copyfd(pip[1], 1, 1);
close(pip[1]);
}
}
evaltree(lp->n, EV_EXIT);
}
if (prevfd >= 0)
close(prevfd);
prevfd = pip[0];
close(pip[1]);
}
if (n->npipe.backgnd == 0) {
exitstatus = waitforjob(jp);
TRACE(("evalpipe: job done exit status %d\n", exitstatus));
}
INTON;
}
case NPIPE:
evalpipe(n);
do_etest = !(flags & EV_TESTED);
break;
...由evalloop中的无限循环调用,并渗透树直到它到达eval函数。我希望这会有所帮助。