shell 1>&2 2>&1 &>filename重定向的含义和区别

转载自:

http://www.jb51.net/article/64183.htm



shell 1>&2 2>&1 &>filename重定向的含义和区别

在 shell 程式中,最常使用的 FD (file descriptor) 大概有三个, 分别是:

0 是一个文件描述符,表示标准输入(stdin)
1 是一个文件描述符,表示标准输出(stdout)

2 是一个文件描述符,表示标准错误(stderr)

在标准情况下, 这些FD分别跟如下设备关联:
stdin(0): keyboard 键盘输入,并返回在前端
stdout(1): monitor 正确返回值 输出到前端
stderr(2): monitor 错误返回值 输出到前端

& 是一个描述符,如果1或2前不加&,会被当成一个普通文件。

1>&2 意思是把标准输出重定向到标准错误.

2>&1 意思是把标准错误输出重定向到标准输出。

&>filename 意思是把标准输出和标准错误输出都重定向到文件filename中


举例说明:

当前目录只有一个文件 a.txt.
[root@redhat box]# ls
a.txt
[root@redhat box]# ls a.txt b.txt
ls: b.txt: No such file or directory 由于没有b.txt这个文件, 于是返回错误值, 这就是所谓的2输出
a.txt 而这个就是所谓的1输出

再接着看:

[root@redhat box]# ls a.txt b.txt 1>file.out 2>file.err
执行后,没有任何返回值. 原因是, 返回值都重定向到相应的文件中了,而不再前端显示
[root@redhat box]# cat file.out
a.txt
[root@redhat box]# cat file.err
ls: b.txt: No such file or directory
一般来说, "1>" 通常可以省略成 ">".
即可以把如上命令写成: ls a.txt b.txt >file.out 2>file.err
有了这些认识才能理解 "1>&2" 和 "2>&1".
1>&2 正确返回值传递给2输出通道 &2表示2输出通道
如果此处错写成 1>2, 就表示把1输出重定向到文件2中.
2>&1 错误返回值传递给1输出通道, 同样&1表示1输出通道.
举个例子.
[root@redhat box]# ls a.txt b.txt 1>file.out 2>&1
[root@redhat box]# cat file.out
ls: b.txt: No such file or directory
a.txt
现在, 正确的输出和错误的输出都定向到了file.out这个文件中, 而不显示在前端.
补充下, 输出不只1和2, 还有其他的类型, 这两种只是最常用和最基本的.

 >是重定向符,就是把前面输出的内容重定向到后面指定的位置,比如(例1):

echo "一些内容" > filename.txt

上面例子会把 "一些内容" 写入到 filename.txt 文件中。

>前是可以加数字来说明把什么内容重定向到文件中,默认是把标准输出重定向到文件中,所以下面这个例子和上面那个是一样的(例2):

echo "一些内容" 1> filename.txt

如果是错误信息就不会输出到filename.txt(例3):

$ ls nodir 1> filename.txt
$ ls: nodir: No such file or directory

上面这个例子中nodir不存在,所以通过ls命令查询时错误信息会输出到 2(stderr),但我们指定的是把1重定向到filename.txt,所以上面命令执行完后,filename.txt中是没有内容的。但是执行下面命令就会把错误信息写入到filename.txt中(例4):

$ ls nodir 2> filename.txt
$ cat filename.txt
$ ls: nodir: No such file or directory

我们再看一个例子(例5):

$ ls nodir 1> filename.txt 2>&1
$ cat filename.txt
$ ls: nodir: No such file or directory

上面例子把 标准输出 重定向到文件 filename.txt,然后把 标准错误 重定向到标准输出,所以最后的错误信息也通过标准输出写入到了文件中,比较例3,4,5,就能明白其作用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的示例程序,可以实现您所需的功能: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/wait.h> #define MAX_LINE 80 #define MAX_ARGS 10 int main(void) { char *args[MAX_ARGS]; char line[MAX_LINE]; int should_run = 1; while (should_run) { printf("my_shell> "); fflush(stdout); fgets(line, MAX_LINE, stdin); int i = 0; int j = 0; int k = 0; int fd_in = 0; int fd_out = 1; int pipefd[2]; int pipe_exists = 0; int background = 0; while (line[i] != '\0') { if (line[i] == ' ' || line[i] == '\t' || line[i] == '\n') { if (k != 0) { args[j] = (char*)malloc(k+1); strncpy(args[j], &line[i-k], k); args[j][k] = '\0'; j++; k = 0; } } else if (line[i] == '&') { background = 1; break; } else if (line[i] == '|') { pipe_exists = 1; pipe(pipefd); fd_out = pipefd[1]; break; } else if (line[i] == '<') { args[j] = NULL; i++; while (line[i] == ' ' || line[i] == '\t') { i++; } k = 0; while (line[i] != ' ' && line[i] != '\t' && line[i] != '\n') { k++; i++; } char *filename = (char*)malloc(k+1); strncpy(filename, &line[i-k], k); filename[k] = '\0'; fd_in = open(filename, O_RDONLY); if (fd_in < 0) { perror("open input file failed"); exit(1); } } else if (line[i] == '>') { args[j] = NULL; i++; while (line[i] == ' ' || line[i] == '\t') { i++; } k = 0; while (line[i] != ' ' && line[i] != '\t' && line[i] != '\n') { k++; i++; } char *filename = (char*)malloc(k+1); strncpy(filename, &line[i-k], k); filename[k] = '\0'; fd_out = open(filename, O_CREAT|O_WRONLY|O_TRUNC, 0666); if (fd_out < 0) { perror("open output file failed"); exit(1); } } else { if (k == 0) { args[j] = (char*)malloc(1); } args[j][k] = line[i]; k++; } i++; } args[j] = NULL; if (background) { pid_t pid = fork(); if (pid < 0) { perror("fork failed"); exit(1); } if (pid == 0) { if (fd_in != 0) { dup2(fd_in, 0); close(fd_in); } if (fd_out != 1) { dup2(fd_out, 1); close(fd_out); } execvp(args[0], args); perror("execvp failed"); exit(1); } } else if (pipe_exists) { pid_t pid1 = fork(); if (pid1 < 0) { perror("fork failed"); exit(1); } if (pid1 == 0) { close(pipefd[0]); if (fd_in != 0) { dup2(fd_in, 0); close(fd_in); } if (fd_out != 1) { dup2(fd_out, 1); close(fd_out); } execvp(args[0], args); perror("execvp failed"); exit(1); } pid_t pid2 = fork(); if (pid2 < 0) { perror("fork failed"); exit(1); } if (pid2 == 0) { close(pipefd[1]); dup2(pipefd[0], 0); close(pipefd[0]); execvp(args[j+1], &(args[j+1])); perror("execvp failed"); exit(1); } close(pipefd[0]); close(pipefd[1]); waitpid(pid1, NULL, 0); waitpid(pid2, NULL, 0); } else { pid_t pid = fork(); if (pid < 0) { perror("fork failed"); exit(1); } if (pid == 0) { if (fd_in != 0) { dup2(fd_in, 0); close(fd_in); } if (fd_out != 1) { dup2(fd_out, 1); close(fd_out); } execvp(args[0], args); perror("execvp failed"); exit(1); } waitpid(pid, NULL, 0); } for (i = 0; i < j; i++) { free(args[i]); } if (fd_in != 0) { close(fd_in); } if (fd_out != 1) { close(fd_out); } } return 0; } ``` 这个程序可以实现基本的命令解释功能,并支持&、<、>和|操作符。请注意,这只是一个简单的示例程序,可能需要进一步调整和优化,以适应实际需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值