赞
踩
$ ps -u
$ ps -u | grep pts
$ ps -u | grep pts | grep pts/0
输入: <
输出: >
追加的方式输入: >>
#include <stdio.h>
int main(int argc,char *argv[]) {
//从标准输入中获取
char str[1024];
scanf("%s",str);
//往标准输出中打印argc argv
printf("argc = %d\n",argc);
for(int i = 0;i<argc;i++){
fprintf( stdout, "%s\n", argv[i]);
}
printf("%s\n",str);
//往标准错误中打印
fprintf(stderr,"this is stderr\n");
return 0;
}
#不重定向
$ ./test
#重定向 执行后不会打印出来,不用再输入参数
$ ./test01 0<in.txt 1>out.txt 2>err.txt
#以追加的方式重定向,不会清空原文件
$ ./test01 2>>err.txt
#要将文本输入到标准输入 只能用 0<xxx.txt
:<<annotation
标准输入 stdin 0
标准输出 stdout 1
标准错误 stderr 2
annotation
结论
重定向由shell实现
重定向符号和重定向文件不是参数
1、先关闭标准输出的文件描述符
2、再打开一个文件
3、这个文件的文件描述符就变成了1,从而实现重定向功能
#include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <stdlib.h> int main(int argc,char *argv[]) { //输出到标准输出 char buf[] = "1234567890\n"; write(1,buf, sizeof(buf) - 1 );//sizeof会计算 \0 //关闭标准输出,重定向到指定文件 close(1); int fd = open("./out.txt",O_CREAT | O_RDWR | O_TRUNC,666); if(fd < 0){ perror("open"); exit(-1); } write(1,buf, sizeof(buf) - 1 ); close(fd); return 0; }
#include <unistd.h>
int dup(int oldfd);
int dup2(int oldfd, int newfd);
功能
复制一个文件描述符
参数说明
oldfd 要复制的文件描述符
newfd 复制后得到的文件描述符返回值
-1 出错
> -1 新的文件描述符
#include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <stdlib.h> int main(int argc,char *argv[]) { int fd = open("./out.txt",O_CREAT | O_RDWR | O_TRUNC,666); if(fd<0){ perror("open"); exit(-1); } //输出到标准输出 char buf[] = "hello\n"; write(1,buf, sizeof(buf) - 1 );//sizeof会计算 \0 //关闭标准输出,重定向到指定fd 方法1 close(1); int newfd = dup(fd); if(newfd != 1){ perror("dup"); exit(-1); } close(fd); write(1,buf, sizeof(buf) - 1 ); close(newfd); //关闭标准输出,重定向到指定fd 方法2 // dup2(fd,1); // if(fd != 1){ // perror("dup2"); // exit(-1); // } // write(1,buf, sizeof(buf) - 1 ); // close(fd); return 0; }
#include <unistd.h>
int pipe(int pfd[2]);
//man 手册是 pipefd,我简写成 pfd;
- 参数说明
pfd 存放管道两端文件描述符的数组
pfd[0] 存放读端的描述符
pfd[1]存放写端的描述符- 返回值
-1 错误
0 成功
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <wait.h> #include <string.h> int main() { int pfd[2]; pid_t pid; char buf[] ="1234567890"; if(pipe(pfd) == -1){ perror("pipe"); exit(-1); } pid = fork(); if(pid<0){ perror("fork"); exit(-1); } else if(pid == 0){ close(pfd[1]); memset(buf,0, sizeof(buf)); read(pfd[0],buf, sizeof(buf) - 1 ); printf("子进程接收 : %s\n",buf); close(pfd[0]); exit(0); } else{ close(pfd[0]); write(pfd[1], buf, sizeof(buf) - 1); printf("父进程发送 : %s \n",buf); close(pfd[1]); wait(NULL); exit(0); } }
#创建一个名为 fifo 的命名管道文件
$ mknod fifo p
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
- 功能
创建命名管道文件- 参数
pathname 要创建的文件名
mode 文件权限- 返回值
0 成功
-1 失败
mkfifo("fifo",0644);
int fd = open("fifo",O_RDWR);
#include <stdio.h>
FILE *popen(const char *command, const char *type);
int pclose(FILE *stream);
- 功能
通过创建管道、fork和调用shell来打开进程- 参数
command:要执行的命令或程序 (实际是打开了子进程)
type:分为 ‘r’和‘w’
r 表示读取command 的输出
w 表示写到command 的输入
#include <stdio.h>
int main() {
char buf[12] = {'\0'};
fgets(buf, sizeof(buf),stdin);
printf("%s\n",buf);
}
#include <stdio.h>
#include <unistd.h>
#include <wait.h>
int main() {
FILE *fp = popen("./hello","w");
int fd = fileno(fp);
char buf[] = "hello world";
write(fd,buf, sizeof(buf) - 1);
wait(NULL);
close(fd);
pclose(fp);
return 0;
}
$ ls -l / | grep lib
#include <stdio.h> #include <unistd.h> #include <wait.h> //为了方便,没写出错处理 int main() { //fork一个子进程执行 ls -l / 并拿到输出结果 FILE *fp = popen("ls -l /","r"); int fd = fileno(fp); //重定向到标准输入 dup2(fd,0); wait(NULL); close(fd); pclose(fp); char* argv[] = {"grep","lib",NULL}; execvp("grep",argv); }
笔记来源:mooc
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。