(Linux学习之笔记)重定向
在Linux里面有三个标准流 :标准输入0,标准输出1,标准错误20,1,2对应的物理设备一般是 : 键盘、显示器、显示器
·
在Linux里面有三个标准流 :标准输入0,标准输出1,标准错误2
0,1,2对应的物理设备一般是 : 键盘、显示器、显示器
通过上图我们看到原本应该输出到显示器上的内容,输出到了文件myfile中,这种现象叫做输出重定向。常见的重定向有>,>>,< 即输出重定向,输出附加定输入向符,输入重定向
1.输出重定向
>>1.概念
把命令的标准输出重定向到指定文件中
>>2.格式
命令>文件名
命令>>文件名
说明: 输出附加定向符( >> )的作用是把命令/程序的输出附加到指定文件的末尾
例子:who>userlog
date>>userlog
>>3.自己实现重定向
运行结果:
2.输入重定向
>>1.概念
让命令从指定文件中取得输入数据
>>2.格式
命令<文件名
例子: bash<ex1 //从脚本文件ex1中取得命令
wc<file //将file作为wc命令的输入>>3.自己实现输入重定向
运行结果:
3.简易的myshell实现输入/输出/追加重定向
def.h
#ifndef __DEF_H__
#define __DEF_H__
#define MAXLINE 1024 // 一行的最大值
#define ARGS 8 // 命令行参数个数
#define MAXPIPE 8 // 系统最多能够解析8个管道
typedef struct command_ {
char *args[ARGS];
int infd;
int outfd;
}command_t;
#endif //__DEF_H__
extern.h
#ifndef __EXTERN_H__
#define __EXTERN_H__
#include "def.h"
extern char cmdline[MAXLINE+1];
extern char avline[MAXLINE+1];
extern command_t cmd[MAXPIPE];
extern int pipenum;
extern int lastpid;
#endif //__EXTERN_H__
inti.h
#ifndef __INIT_H__
#define __INIT_H__
void sig_init();
void init();
#endif // __INIT_H__
parse.h
#ifndef __PARSE_H__
#define __PARSE_H__
void shell_loop();
int cmd_read();
int cmd_parse();
int cmd_execute();
#endif // __PARSE_H__
init.c
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "init.h"
#include "extern.h"
void handler(int s)
{
printf("\n[sxshell]: ");
fflush(stdout);
}
void sig_init()
{
signal(SIGINT, handler);
signal(SIGQUIT, SIG_IGN);
}
// 初始化全局变量
void init()
{
memset(cmdline, 0x00, sizeof(cmdline));
memset(avline, 0x00, sizeof(avline));
for (int k=0; k<MAXPIPE; k++) {
for (int i=0; i<ARGS; i++)
cmd[k].args[i] = NULL;
cmd[k].infd = 0;
cmd[k].outfd = 1;
}
pipenum = 0;
}
parse.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include "parse.h"
#include "extern.h"
#include "init.h"
static void cmd_print()
{
for (int i=0; i<=pipenum; i++) {
printf("i=%d\n", i);
for (int j=0; cmd[i].args[j]!=NULL; j++) {
printf("\t[%s]\n", cmd[i].args[j]);
}
}
}
void shell_loop()
{
while ( 1 ) {
printf("[sxshell]: ");
init();
if ( cmd_read() == 0 )
break;
cmd_print();
cmd_parse();
cmd_execute();
}
printf("\n");
}
/* 读取命令行参数 */
/* 返回值: 成功, 1;失败,0 */
int cmd_read()
{
return (fgets(cmdline, MAXLINE, stdin)==NULL) ? 0 : 1;
}
// 解析命令行参数
int cmd_parse()
{
char *p = cmdline;
char *q = avline;
for (int i=0; i<MAXPIPE && *p!='\0'; ++i) {
for (int j=0; j<ARGS && *p!='\0'; ++j) {
while ( *p!='\0' && (*p==' ' || *p=='\t' || *p=='\n') )
p++;
cmd[i].args[j] = q;
while ( *p!='\0' && *p!=' ' &&
*p!='\t' && *p!='\n' && *p!='|' ) {
*q++ = *p++;
}
*q++ = '\0';
if ( *p == '|' ) {
pipenum++;
p++;
cmd[i].args[j] = NULL;
break;
}
if ( *p=='\n' ) {
cmd[i].args[j+1] = NULL;
break;
}
}
}
return 0;
}
// 执行指令
int cmd_execute()
{
int fds[2];
for (int i=0; i<=pipenum; i++){
if ( i< pipenum ) {
pipe(fds);
cmd[i].outfd = fds[1];
cmd[i+1].infd = fds[0];
}
pid_t pid = fork();
if ( pid == 0 ) {
if ( cmd[i].infd != 0 ) {
close(0);
dup(cmd[i].infd);
}
if ( cmd[i].outfd != 1 ) {
close(1);
dup(cmd[i].outfd);
}
execvp(cmd[i].args[0], cmd[i].args);
exit(1);
}else {
if ( cmd[i].infd != 0 )
close(cmd[i].infd);
if ( cmd[i].outfd != 1 )
close(cmd[i].outfd);
lastpid = pid;
}
while ( wait(NULL) != lastpid)
;
return 0;
}
main.c
#include "parse.h"
#include "def.h"
#include "init.h"
command_t cmd[MAXPIPE]; // 命令行参数
char cmdline[MAXLINE+1]; // 读取命令行数据
char avline[MAXLINE+1]; // 处理后的数据
int pipenum; // 当前用了几个管道符
int lastpid;
int main( void )
{
sig_init();
shell_loop();
return 0;
}
Makefile
.PHONY : clean sxshell
OBJS = main.o\
parse.o\
init.o
CC=cc
CFLAGS=-Wall -g
sxshell : $(OBJS)
$(CC) $(CFLAGS) -o $@ $(OBJS) -std=gnu99
%.o : %.c
$(CC) -c $< -o $@ -std=gnu99
clean:
rm -rf $(OBJS)
运行结果:
更多推荐
已为社区贡献1条内容
所有评论(0)