4

linux学习5,自制linux命令

 3 years ago
source link: https://blog.popkx.com/linux-learning-5-homemade-linux-commands/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

linux学习5,自制linux命令

发表于 2018-12-08 15:12:19   |   已被 访问: 425 次   |   分类于:   Linux笔记   |   暂无评论

前面四节介绍了如何定制自己的 linux。我们一起下载和编译了 linux 内核,又使用 busybox 配置了文件系统,然后使用 qemu 模拟运行了 linux,成就感大大的。在这几节,我们使用了大量的 linux 命令,命令式的操作与 windows 的界面操作方式差别很大。不过,本节不介绍 linux 有哪些命令,也不介绍怎么使用,而是介绍如何自己制作 linux 风格的命令

f2b387fff01dddb1924a71a0240589a9.png

不知道大家怎么样,反正我当初刚接触 linux 时,觉得命令操作很新奇,尤其是还可以附加参数,例如 ls 命令只是简单的列出当前目录的文件,而加上 -ahl,就不仅仅列出文件了,还把各个文件的权限,用户组,时间等信息也列出了。

# ls
bus_error  continue  is_float  thread_priority  tmp
#
# ls -ahl
total 28K
drwxr-xr-x 7 root root 4.0K Nov 29 22:36 .
drwxr-xr-x 9 root root 4.0K Nov 29 22:14 ..
drwxr-xr-x 2 root root 4.0K Nov 29 22:21 bus_error
drwxr-xr-x 2 root root 4.0K Nov 29 22:32 continue
drwxr-xr-x 2 root root 4.0K Nov 29 22:21 is_float
drwxr-xr-x 2 root root 4.0K Oct 31 17:39 thread_priority
drwxr-xr-x 2 root root 4.0K Nov 29 22:46 tmp

这实际上也是 linux 系统的命令式操作的一大特色。习惯使用 windows 的人,猛然使用这种命令式操作一般都会觉得不适应,看起来,鼠标都没用了。其实,用习惯了,会发现 linux 的这种命令式操作,效率更高。

7df5da4809835689c3a85db00da77342.png

例如,希望查看当前目录下的每一个文件的最后修改时间,在 windows 上使用鼠标操作时,需要一个一个的右键,再左键查看属性,繁琐了很多。事实上,就 ls 命令而言,它的功能远不止我们上面列出的那样,例如:

# ls tmp/
t.c

ls + 目录,就可以查看指定目录里的文件。那么,linux 的这些命令是怎么实现的呢?我们自己能使用 C 语言制作一个这种风格的命令吗?答案当然是肯定的。我们还是从实例出发,介绍一下怎样制作这种命令。作为示范,我们的命令功能不需要很复杂,哪怕只是打印一句 hello world 就可以了。这样的 C 语言程序,相信大家都会写。

如果有希望从头学习 C 语言的朋友,可以看看我的《C语言入门》系列文章。

//文件名 t.c
#include <stdio.h>
int main()
{
    printf("hello, embed time\n");
    return 0;
}

编写完代码,我们编译它,然后就可以执行了:

# gcc t.c -o mycmd
# ./mycmd
hello, embed time
8079eb4dc6a2e3858c303dfebcf7fc7f.png

可能你会说,什么嘛,不就是执行了一个程序吗?是的,linux 的命令其实也就是一个程序而已。可是,linux 的命令不需要 ./ 符号就能执行啊,我们的却不行:
# mycmd
mycmd: command not found

提示找不到 mycmd 命令。这是当然的了,linux 的目录这么多,它不可能每一个目录都找找,这样系统岂不是卡死了?事实上,linux 一般去 PATH 环境变量记录的目录里去找命令:

# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

上面我们把 linux 会查找的目录打印出来了,可以看出,并没有 mycmd 所在目录。那我们把 mycmd 目录添加到 PATH 里就好了吗?是的,请看:

# export PATH=$PATH:<你的mycmd所在路径>
# mycmd
hello, embed time

看到没?现在我们自己定义的 mycmd 很像 linux 命令了吧~ 可是,mycmd 命令能接受 ls 命令的 -ahl 那样的参数吗?现在还不能,所以我们继续。作为示范,这里我们计划为 mycmd 命令增加这样的参数:

mycmd       输出 hello, embed time
mycmd -s        输出 hello, sweety
mycmd -h        输出 hello, world
mycmd -其他       输出 error parameter

怎么实现呢?以前开发 C 语言程序时,我们写 main 函数时,通常都是写 int main(),把 main 函数的参数定义为空,实际上 main 函数是能够接受参数的,它完整的原型如下:

int main(int argc, char* argv[]);
781b25194d3348a0e4a0af40be4293e3.png

argc 表示有几个参数,argv 则记录着这些参数。例如我们输入 mycmd 时,argc 就为 1,argv[0] 则记录着 "mycmd" 的地址。这么说有些虚,我们来实现上面的带参数的 mycmd 命令:
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[])
{
    if(argc<2){
        printf("hello, embed time\n");
    }else{
        if(!strcmp(argv[1], "-s"))
            printf("hello, sweety\n");
        else if(!strcmp(argv[1], "-h"))
            printf("hello, world\n");
        else
            printf("error parameter\n");
    }
    return 0;
}
48e1b32ecdf6a714812b4a49a5c82d44.png

如果我们只输入 mycmd,则参数只有一个,即 argc<2,程序输出 hello, embed time。否则程序就会根据第二个参数决定输出字符串。我们编译,测试:
# gcc t.c -o mycmd
# mycmd
hello, embed time
# mycmd -s
hello, sweety
# mycmd -h
hello, world
# mycmd -y
error parameter

可以看出,我们自己定义的 mycmd 也可以带参数了。看来,linux 风格的命令也没那么神秘嘛,对不?


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK