简单shell 命令重定向

今天晚上花了一会写的,开始用的是 argv 是个二位数组, 调程序的时候总是显示不出,后来发现execvp貌似只支持 pointer array =。= 好吧。。。。
程序思路:开子进程以后把 子进程的标准输出 关闭, 然后在子进程中新建一个文件,此时文件会选择 自身进程中最小的文件标识符 作为该文件的文件标识符,也就是fd

所以,以后子进程的所有标准输出都流向了文件, 这个应该是简单的思路了吧,感觉GNU的源码应该是用无名管道,甚至是有名管道(网络传输) 实现的,好吧我就不意淫了。。。 有兴趣的朋友可以去官网上找找 GNU/Linux 的shell 源代码

/*  1.c
 *  author:wangshiyang
 *  date: 2013/5/13
 */

#include <stdio.h>
#include <unistd.h>
#include <string.h>
//------------------------------------------------------
/* for the convience I'v set a lot of global-variables |
 * the formal shell program may not dit like this	   |
 * */			// warning: use argv[][] is wrong !!!  |
char input[100];// the command you input               |
char *argv[30];//the execvp must use point array	   |
char file[100];//you can input a filename              |
//------------------------------------------------------
char *newstr( char *s, int l )
{
	char * rv = (char *)malloc( l+1 );
	rv[l] = '\0';
	strncpy( rv, s, l);
	return rv;
}
int deal()			// deal the input command
{
	char temp[100];
	int len, i, a, turn;
	fgets(input, 100, stdin);
	len = strlen(input);
	turn = 0; a = 0; 
	for( i = 0; i < len; i++ )
	{
		if( input[i] == '\n' )
		{
			argv[turn++] = newstr( temp, strlen(temp) );
			break;
		}
		if( input[i] != ' ' )
		{
			temp[a++] = input[i];
			temp[a] = '\0';
		}
		else
		{
			argv[turn++] = newstr( temp, strlen(temp) );
			a = 0;
		}
	}
	for( i = 0; i < turn; i++ )
		if( !strcmp( argv[i], ">" ))
		{
			strcpy( file, argv[i+1]);	//copy the filename to file array
			return i;
		}
	return -1;
};
void execute( int flag )	// run the command 
{
	int	pid, fd;
	argv[flag] = NULL;
	if( (pid = fork() ) == -1 )
	{
		perror( "fork" ); 
		exit(1);
	}
	if ( pid == 0 )
	{
		/* 0 for stdin, 1 for stdout, 2 for stderr */
		close(1);		// close the stdout 
		fd = creat( file, 0777 );// then open and fd connect to 1
		execvp( argv[0], argv );// and run	
		perror( "execvp" );
		exit(1);
	}
	if ( pid != 0 )
	{
		wait(NULL);
		printf( "Father Done\n" );
	}
};
void free_all( )	// free all the pointers
{
	int i;
	for( i = 0; i < 30; i++ )
		free(argv[i]);
	printf( "All the pointer have been free.." )
};
int main()
{
	int flag;
	printf( "Please input a command,please using the '>'\n" );
	printf( "example: ls -ail > 123 \n" );
	flag = deal();
	if( flag == -1 )
	{
		fprintf( stderr, "input wrong! do not include '>'\n");
		exit(1);
	}
	execute( flag );
	free_all();
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Linux 中使用 C 语言实现 shell 命令 <> 的重定向,可以使用 dup2() 函数来实现。dup2() 函数可以将一个文件描述符的内容复制到另一个文件描述符中,从而实现文件重定向。 下面是一个简单的示例程序,可以实现 “<” 和 “>” 的文件重定向功能: ```c #include <stdio.h> #include <unistd.h> #include <fcntl.h> int main(int argc, char *argv[]) { int in_fd, out_fd; char *in_file, *out_file, *cmd; if (argc != 4) { fprintf(stderr, "Usage: %s <input_file> <output_file> <command>\n", argv[0]); return 1; } in_file = argv[1]; out_file = argv[2]; cmd = argv[3]; // 打开输入文件 in_fd = open(in_file, O_RDONLY); if (in_fd == -1) { perror("open input file"); return 2; } // 打开输出文件 out_fd = open(out_file, O_CREAT|O_WRONLY|O_TRUNC, 0644); if (out_fd == -1) { perror("open output file"); return 2; } // 将输入文件重定向到标准输入 if (dup2(in_fd, STDIN_FILENO) == -1) { perror("dup2 input file"); return 3; } // 将输出文件重定向到标准输出 if (dup2(out_fd, STDOUT_FILENO) == -1) { perror("dup2 output file"); return 3; } // 执行命令 if (system(cmd) == -1) { perror("system command"); return 4; } // 关闭文件 close(in_fd); close(out_fd); return 0; } ``` 在上面的程序中,我们首先打开输入文件和输出文件,并将它们分别重定向到标准输入和标准输出。然后执行传入的命令命令的输出将被重定向到输出文件中。最后关闭文件描述符。 使用该程序可以实现以下命令的效果: ```bash $ ./redirect input.txt output.txt wc -l ``` 该命令会将输入文件 input.txt 的内容通过 “<” 重定向到 wc 命令的标准输入中,将 wc 的输出通过 “>” 重定向到 output.txt 文件中。最后输出文件 output.txt 中行数的结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值