编写简单shell

来源:互联网 发布:金山卫士 源码 编辑:程序博客网 时间:2024/05/21 09:35

        shell英文翻译为外壳,壳的意思;而在linux操作系统中,我们将它作为操作系统的外壳来理解。对shell工作原理的感性认识,shell在运行指令时,看似运行指令,实际是创建了shell的子进程来代替父进程shell来运行指令,此时子进程运行指令并不是shell的指令,而是一个全新的指令。这里就运用了linux进程控制主题下的进程程序替换。

        子进程程序替换的步骤 :1.创建子进程;2.将硬盘上的新程序加载到物理内存中去;3.让子进程通过页表映射到物理内存中新代码的位置,从此子进程在代码和数据上与父进程没有任何关系(除血缘关系)。

          linux采用exec进程程序替换家族函数来进行程序的替换,共有六个函数


函数的返回值:

          这些函数如果调.用成功则加载新的程序从启动代码开始执行,不再返回,如果调用出错则返回-1, 所以exec函数只有出错的返回值.而没有成功的返回值。



以上六个函数各有不同,主要在后缀字码l与v、p、e的含义不同函数的参数形式也不相同

  • execl与execv         
                两者不同在于第二个参数,第二个参数代表输入命令行的参数,execl函数以l结尾,第二个参数为可变列        表的形式(...), execv函数以v结尾,第二个参数用指针数组来代替,数组元素指向一个个字符串。但参数都是以          NULL 结尾。
  • execlp与execvp都是以p做为后缀
                函数后缀不带p,第一个参数必须是程序的相对路径和绝对路径,‘.’表示当前路径,‘\’表示根目录;函数后缀        带p,则第一个参数可以是程序名,也可以加/表示路径。
  • execle与execve都是以e字母结尾
                函数后缀带有e,则第三个参数表示环境变量,可以重新传一个新的环境变量给函数;不带后缀e,则函数         exec使用当前的环境变量运行程序。

只有函数execve是真正系统调用的函数,其余五个函数最终调用的都是execve函数。


简单myshell的编写步骤:
  1. 创建一个子进程
  2. 在子进程中执行一条运行命令,该运行命令能够与系统执行的结果相同
  3. 父进程等待子进程结束并回收
myshell命令的编写截图:




myshell编写涉及的函数:

参数:fd表示文件描述符,buf表示读取到的内容存储到buf中,count表示期望读到的字节数。即期望从标识符为fd的文件中读取到count字节数(常用sizeof()求取)的内容放到buf中去。
返回值:

当返回值大于0,表示读取成功,且没有读到文件的尾端,返回值表示读取到的字符个数;当返回值等于0,表示读到文件的结尾(当停止向文件写入内容,只读的话,一段时间之后,就会读到文件结尾);当返回值小于0,表示读取失败。

进程等待函数


参数:pid表示要等待子进程的标识,status是输出型的参数,表示子进程的退出消息,32位我们之关心低16位,次第八位表示子进程的退出码,第八位表示子进程退出时收到的退出信号。options表示父进程等待的状态,有两种,阻塞式等待(options置0),非阻塞式等待(options置为WNOHANG);
           要得到退出码与退出信号,我们可以用移位操作(退出码:(status>>8)&oxff  退出信号:(status)&oxff);也可以用宏。
WIFEXITED(status) : 若为正常终止子进程返回的状态,则为真。(查看进程是否是正常退出)WEXITSTATUS(status) : 若WIFEXITED非零,提取子进程退出码。
返回值:若子进程正常退出,则返回子进程的ID,否则返回-1.

0 0