首页编程shell编程 请问shell编程是什么请高手指点!

shell编程 请问shell编程是什么请高手指点!

编程之家2023-11-02112次浏览

亲爱的读者们,你是否对shell编程和请问shell编程是什么请高手指点!的相关问题感到困惑?别担心,今天我将为你解答这些问题,让你对此有更清晰的认识。

shell编程 请问shell编程是什么请高手指点!

简单的shell编程

#include<unistd.h>

#include<sys/types.h>

#include<sys/wait.h>

#include<stdlib.h>

#include<sys/stat.h>

#include<fcntl.h>

shell编程 请问shell编程是什么请高手指点!

#define BUFFERSIZE 80

extern char*get_current_dir_name(void);

extern char*getenv(const char*name);

extern pid_t waitpid(pid_t pid, int*status, int options);

char buffer[BUFFERSIZE+1];

main()

shell编程 请问shell编程是什么请高手指点!

{

char*path,*arg[10],*input;

int li_inputlen, is_bj, is_back, i, j, k, pid, status;

char lc_char;

while(1){

/* initiations*/

is_bj= 0;/*redirection flag*/

is_back= 0;/*background*/

/* shell prompt*/

path= get_current_dir_name();

printf("%s>$",path);

/*开始获取输入*/

li_inputlen= 0;

lc_char= getchar();

while(lc_char!='\n'){

if(li_inputlen< BUFFERSIZE)

buffer[li_inputlen++]= lc_char;

lc_char= getchar();

}

/*命令超长处理*/

if(li_inputlen>= BUFFERSIZE){

printf("Your command is too long! Please re-enter your command!\n");

li_inputlen= 0;/*reset*/

continue;

}

else

buffer[li_inputlen]='\0';/*加上串结束符号,形成字串*/

/*将命令从缓存拷贝到input中*/

input=(char*) malloc(sizeof(char)*(li_inputlen+1));

strcpy(input,buffer);

/*获取命令和参数并保存在arg中*/

for(i= 0,j= 0,k= 0;i<= li_inputlen;i++){

/*管道和重定向单独处理*/

if(input[i]=='<'|| input[i]=='>'|| input[i]=='|'){

if(input[i]=='|')

pipel(input,li_inputlen);

else

redirect(input,li_inputlen);

is_bj= 1;

break;

}

/*处理空格、TAB和结束符。不用处理‘\n',大家如果仔细分析前面的获取输入的程序的话,

*不难发现回车符并没有写入buffer*/

if(input[i]==''|| input[i]=='\t'|| input[i]=='\0'){

if(j== 0)/*这个条件可以略去连在一起的多个空格或者tab*/

continue;

else{

buffer[j++]='\0';

arg[k]=(char*) malloc(sizeof(char)*j);

/*将指令或参数从缓存拷贝到arg中*/

strcpy(arg[k],buffer);

j= 0;/*准备取下一个参数*/

k++;

}

}

else{

/*如果字串最后是‘&',则置后台运行标记为1*/

if(input[i]=='&'&& input[i+1]=='\0'){

is_back= 1;

continue;

}

buffer[j++]= input[i];

}

}

free(input);/*释放空间*/

/*如果输入的指令是leave则退出while,即退出程序*/

if(strcmp(arg[0],"leave")== 0){

printf("bye-bye\n");

break;

}

/*如果输入的指令是about则显示作者信息,同时结束本条命令的解析过程*/

if(strcmp(arg[0]," about")== 0){

printf("copyright by shike,shike13@163.com\n");

continue;

}

if(is_bj== 0){/*非管道、重定向指令*/

/*在使用xxec执行命令的时候,最后的参数必须是NULL指针,

*所以将最后一个参数置成空值*/

arg[k]=(char*) 0;

/*判断指令arg[0]是否存在*/

if(is_fileexist(arg[0])==-1){

printf("This command is not found?!\n");

for(i=0;i<k;i++)

free(arg[i]);

continue;

}

/* fork a sub-process to run the execution file*/

if((pid= fork())==0)/*子进程*/

execv(buffer,arg);

else/*父进程*/

if(is_back== 0)/*并非后台执行指令*/

waitpid(pid,&status,0);

/*释放申请的空间*/

for(i=0;i<k;i++)

free(arg[i]);

}

}

}

int is_fileexist(char*comm)

{

char*path,*p;

int i;

i= 0;

/*使用getenv函数来获取系统环境变量,用参数PATH表示获取路径*/

path= getenv("PATH");

p= path;

while(*p!='\0'){

/*路径列表使用‘:’来分隔路径*/

if(*p!=':')

buffer[i++]=*p;

else{

buffer[i++]='/';

buffer[i]='\0';

/*将指令和路径合成,形成pathname,并使用access函数来判断该文件是否存在*/

strcat(buffer,comm);

if(access(buffer,F_OK)== 0)/*文件被找到*/

return 0;

else

/*继续寻找其它路径*/

i= 0;

}

p++;

}

/*搜索完所有路径,依然没有找到则返回-1*/

return-1;

}

int redirect(char*in,int len)

{

char*argv[30],*filename[2];

pid_t pid;

int i,j,k,fd_in,fd_out,is_in=-1,is_out=-1,num= 0;

int is_back= 0,status=0;

/*这里是重定向的命令解析过程,其中filename用于存放重定向文件,

*is_in, is_out分别是输入重定向标记和输出重定向标记*/

for(i= 0,j= 0,k= 0;i<= len;i++){

if(in[i]==''||in[i]=='\t'||in[i]=='\0'||in[i]=='<'||in[i]=='>'){

if(in[i]=='>'|| in[i]=='<'){

/*重定向指令最多'<','>'各出现一次,因此num最大为2,

*否则认为命令输入错误*/

if(num< 3){

num++;

if(in[i]=='<')

is_in= num- 1;

else

is_out= num- 1;

/*处理命令和重定向符号相连的情况,比如ls>a*/

if(j> 0&& num== 1){

buffer[j++]='\0';

argv[k]=(char*) malloc(sizeof(char)*j);

strcpy(argv[k],buffer);

k++;

j= 0;

}

}

else{

printf("The format is error!\n");

return-1;

}

}

if(j== 0)

continue;

else{

buffer[j++]='\0';

/*尚未遇到重定向符号,字符串是命令或参数*/

if(num== 0){

argv[k]=(char*) malloc(sizeof(char)*j);

strcpy(argv[k],buffer);

k++;

}

/*是重定向后符号的字符串,是文件名*/

else{

filename[status]=(char*) malloc(sizeof(char)*j);

strcpy(filename[status++],buffer);

}

j= 0;/*initate*/

}

}

else{

if(in[i]=='&'&& in[i+1]=='\0'){

is_back= 1;

continue;

}

buffer[j++]= in[i];

}

}

argv[k]=(char*) 0;

if(is_fileexist(argv[0])==-1){

printf("This command is not founded!\n");

for(i=0;i<k;i++)

free(argv[i]);

return 0;

}

if((pid= fork())==0){

/*存在输出重定向*/

if(is_out!=-1)

if((fd_out=open(filename[is_out],O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR))==-1){

printf("Open out%s Error\n",filename[is_out]);

return-1;

}

/*存在输入重定向*/

if(is_in!=-1)

if((fd_in=open(filename[is_in],O_RDONLY,S_IRUSR|S_IWUSR))==-1){

printf("Open in%s Error\n",filename[is_out]);

return-1;

}

if(is_out!=-1)

/*使用dup2函数将标准输出重定向到fd_out上,dup2(int oldfd,int newfd)实现的

*是把oldfd所指的文件描述符复制到newfd。若newfd为一已打开的文件描述词,

*则newfd所指的文件会先被关闭,dup2复制的文件描述词与原来的文件描述词

*共享各种文件状态*/

if(dup2(fd_out,STDOUT_FILENO)==-1){

printf("Redirect Standard Out Error\n");

exit(1);

}

if(is_in!=-1)

if(dup2(fd_in,STDIN_FILENO)==-1){

printf("Redirect Standard Out Error\n");

exit(1);

}

execv(buffer,argv);

}

else

if(is_back== 0)/*run on the TOP*/

waitpid(pid,&status,0);

for(i=0;i<k;i++)

free(argv[i]);

if(is_in!=-1){

free(filename[is_in]);

close(fd_in);

}

if(is_out!=-1){

free(filename[is_out]);

close(fd_out);

}

return 0;

}

int pipel(char*input,int len)

{

char*argv[2][30];

int i,j,k,count,is_back= 0;

int li_comm= 0,fd[2],fpip[2];

char lc_char,lc_end[1];

pid_t child1,child2;

/*管道的命令解析过程*/

for(i= 0,j= 0,k= 0;i<= len;i++){

if(input[i]==''|| input[i]=='\t'|| input[i]=='\0'|| input[i]=='|'){

if(input[i]=='|')/*管道符号*/

{

if(j> 0)

{

buffer[j++]='\0';

/*因为管道连接的是两个指令,所以用二维数组指针来存放命令和参数,

*li_comm是表示第几个指令*/

argv[li_comm][k]=(char*) malloc(sizeof(char)*j);

strcpy(argv[li_comm][k++],buffer);

}

argv[li_comm][k++]=(char*) 0;

/*遇到管道符,第一个指令完毕,开始准备接受第二个指令*/

li_comm++;

count= k;

k=0;j=0;

}

if(j== 0)

continue;

else

{

buffer[j++]='\0';

argv[li_comm][k]=(char*) malloc(sizeof(char)*j);

strcpy(argv[li_comm][k],buffer);

k++;

}

j= 0;/*initate*/

}

else{

if(input[i]=='&'&& input[i+1]=='\0'){

is_back= 1;

continue;

}

buffer[j++]= input[i];

}

}

argv[li_comm][k++]=(char*) 0;

if(is_fileexist(argv[0][0])==-1){

printf("This first command is not found!\n");

for(i=0;i<count;i++)

free(argv[0][i]);

return 0;

}

/*指令解析结束*/

/*建立管道*/

if(pipe(fd)==-1){

printf("open pipe error!\n");

return-1;

}

/*创建第一个子进程执行管道符前的指令,并将输出写到管道*/

if((child1= fork())==0){

/*关闭读端*/

close(fd[0]);

if(fd[1]!= STDOUT_FILENO){

/*将标准输出重定向到管道的写入端,这样该子进程的输出就写入了管道*/

if(dup2(fd[1],STDOUT_FILENO)==-1){

printf("Redirect Standard Out Error\n");

return-1;

}

/*关闭写入端*/

close(fd[1]);

}

execv(buffer,argv[0]);

}

else{/*父进程*/

/*先要等待写入管道的进程结束*/

waitpid(child1,&li_comm,0);

/*然后我们必须写入一个结束标记,告诉读管道进程数据到这里就完了*/

lc_end[0]= 0x1a;

write(fd[1],lc_end,1);

close(fd[1]);

if(is_fileexist(argv[1][0])==-1){

printf("This command is not founded!\n");

for(i=0;i<k;i++)

free(argv[1][i]);

return 0;

}

/*创建第二个进程执行管道符后的指令,并从管道读输入流*/

if((child2= fork())== 0){

if(fd[0]!= STDIN_FILENO){

/*将标准输入重定向到管道读入端*/

if(dup2(fd[0],STDIN_FILENO)==-1){

printf("Redirect Standard In Error!\n");

return-1;

}

close(fd[0]);

}

execv(buffer,argv[1]);

}

else/*父进程*/

if(is_back== 0)

waitpid(child2,NULL,0);

}

for(i=0;i<count;i++)

free(argv[0][i]);

for(i=0;i<k;i++)

free(argv[1][i]);

return 0;

}

以前写的,好像一些细节不一样,不明白的地方,发邮件给我,shike13@163.com

请问shell编程是什么请高手指点!

shell是一个命令处理器(command processor)——是一个读入并解释你输入的命令的程序。除了是一个命令中断器以外,shell还是一个程序设计语言。你可以编写shell可以解释的程序(被称为源程序),这些源程序可以包含shell程序设计命令等等。shell除了解释命令以外,还有其他工作,它也可以配置和编程。shell拥有自己的语言允许用户编写程序并以一种复杂方式运行。shell编程语言具有许多常用的编程语言的特征,例如:循环和控制结构等。用户可以生成像其他应用程序一样复杂的shell程序。

补充说明:简单的说: shell是一个交互性命令解释器。shell独立于操作系统,这种设计让用户可以灵活选择适合自己的shell。shell让你在命令行键入命令,经过shell解释后传送给操作系统(内核)执行。

一下是shell功能的一个汇总:

查找命令的位置并且执行相关联的程序。

为shell变量赋新值

执行命令替代

处理 I/O重定向和管道功能

提供一个解释性的编程语言界面,包括tests、branches和loops等语句

VB中的shell函数是干什么的怎么用啊

Shell函数是VB中的内部函数,它负责执行一个可执行文件,返回一个Variant(Double),如果成功的话,代表这个程序的进程ID,若不成功,则会返回0,shell一个非常重要的特性是它可作为一种编程语言来使用。

Shell的语法:Shell(PathName[,WindowStyle])。

PathName为必需参数,类型为String,它指出了要执行的程序名,以及任何需要的参数或命令行变量。

扩展资料:

因为shell是一个解释器,所以它不能对为它编写的程序进行编译,而是在每次从磁盘加载这些程序时对它们进行解释,而程序的加载和解释都是非常耗时的。

针对此问题,许多shell(如BourneAgainShell)都包含shell函数,shell把这些函数放在内存中,这样每次需要执行它们时就不必再从磁盘读入。

参考资料来源:百度百科-shell函数

什么是shell编程啊,求简单实例

刚刚学习了新书<<实用Linux Shell编程>>,书写的容易懂,第一章就回答了什么是shell编程的问题。下面简单回答,仅供参考,谢谢!

1)linux命令,你可以一条一条执行,例如,显示日期时间命令是date,显示当前目录的命令是pwd,打印一句话的命令可以是echo"good morning"

2)一个脚本是包含多条命令的文本文件,命令将按照顺序依次运行。例如z.sh包含4行,如下:

$ cat z.sh

#!/bin/bash

date

pwd

echo"good morning"

第一行为脚本解释程序的位置/bin/bash,其他行,是命令的“堆放”

3)增加脚本执行权限:

$ chmod+x z.sh

4)运行脚本:

$ z.sh(或者./z.sh)

Mon Jan 12 15:20:32 CST 2015

/home/user

good morning

输出有3行,分别是命令date的结果,命令pwd的结果,命令echo"good morning"的运行结果。

5)一般地,脚本不单单是几个简单命令的“堆放”,有判断、分支选择命令,循环命令,参数输入,函数定义等等。

但是最简单的shell脚本可以就一条命令,或者就几个简单命令的“堆放”。

仅供参考,谢谢!

END,本文到此结束,如果可以帮助到大家,还望关注本站哦!

随州网站建设公司(随州市红佳能网络科技有限公司怎么样)微信工作平台开发,微信公众平台开发需要哪些工具