实现自己的Shell命令(外部命令)

Shell 命令分为两种:

  • Shell 自带的命令称为内置命令,它在 Shell 内部可以通过函数来实现,当 Shell 启动后,这些命令所对应的代码(函数体代码)也被加载到内存中,所以使用内置命令是非常快速的。
  • 更多的命令是外部的应用程序,一个命令就对应一个应用程序。运行外部命令要开启一个新的进程,所以效率上比内置命令差很多。

用户输入一个命令后,Shell 先检测该命令是不是内置命令,如果是就执行,如果不是就检测有没有对应的外部程序:有的话就转而执行外部程序,执行结束后再回到 Shell;没有的话就报错,告诉用户该命令不存在。

内置命令

内置命令不宜过多,过多的内置命令会导致 Shell 程序本身体积膨胀,运行 Shell 程序后就会占用更多的内存。Shell 是一个常驻内存的程序,占用过多内存会影响其它的程序。

只有那些最常用的命令才有理由成为内置命令,比如 cd、kill、echo 等。

外部命令

使用 echo 命令输出 PATH 变量的值,该变量就保存了 Shell 对外部命令的查找路径。

[root123@localhost /]$ echo $PATH
/usr/java/jdk1.8.0_131/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/root123/addon:/home/root123/.local/bin:/home/root123/bin

不同的路径之间以:分隔。Shell 只会在几个固定的路径中查找外部命令。

如果我们自己用C语言或者 C++ 编写一个应用程序,并将它放到这几个目录下面,那么我们的程序也会成为 Shell 命令。当然,你也可以修改 PATH 变量给它增加另外的路径。

下边,使用C语言编写了一个叫做 getsum 的程序,它用来计算从 m 累加到 n 的和,代码如下:

#include 
#include 
#include 
#include 

int main(int argc, char *argv[]){
    int start = 0;
    int end = 0;
    int sum = 0;
    int opt;
    char *optstring = ":s:e:";

    while((opt = getopt(argc, argv, optstring))!= -1){
        switch(opt){
            case 's': start = atoi(optarg); break;
            case 'e': end = atoi(optarg); break;
            case ':': puts("Missing parameter"); exit(1);
        }
    }
   
    if(start<0 || end<=start){
        puts("Parameter error"); exit(2);
    }
   
    for(int i=start; i<=end; i++){
        sum+=i;
    }
    printf("%d\n", sum);

    return 0;
}

将这段代码编译成名为 getsum 的应用程序,并放在~/bin目录(~ 表示用户主目录)下,然后在 Shell 中输入下面的命令,就可以计算 1+2+3 ...... +99+100 的值。

[root123@localhost bin]$ pwd
/home/root123/bin  #这个是我自己配置的PATH路径
[root123@localhost bin]$ ll
total 12
-rwxrwxr-x. 1 root123 root123 8758 Apr 10  2019 getsum
[root123@localhost bin]$ getsum -s 1 -e 100
5050

-s选项表示起始数字,-e选项表示终止数字。

总结

Shell 内置命令的本质是一个自带的函数,执行内置命令就是调用这个自带的函数。因为函数代码在 Shell 启动时已经被加载到内存了,所以内置命令的执行速度很快。

Shell 外部命令的本质是一个应用程序,执行外部命令就是启动一个新的应用程序。因为要创建新的进程并加载应用程序的代码,所以外部命令的执行速度很慢。

你可能感兴趣的:(Shell,linux,bash,centos,shell命令)