3 Copyright (C) 2022- Free Software Foundation, Inc.
5 Copying and distribution of this file, with or without modification,
6 are permitted in any medium without royalty provided the copyright
7 notice and this notice are preserved.
9 The following contributions warranted legal paper exchanges with the
10 Free Software Foundation.
14 shlib最初是用于dvar-shlib编写时的一个脚本库,在使用中觉得这些函数库应该能在其它程序中使用,就像动态链接库的程序一样,所以将shlib从dvar中单独列成一个软件包。在shlib的编写中,随着功能的添加,shlib中一些功能是dvar-shlib用不到的,所以单独列一个lite版本,作为dvar-shlib的依赖库,如果有需要,还可以将shlib-lite的代码调整后,作为dvar-shlib的一部分使用,这样减少dvar-shlib的依赖软件包。
15 脚本程序通常用于单个程序文件的命令行批处理程序应用,通常不太会以"程序库"的形式使用。
16 而脚本编程也有很多优点,它不需要额外的软件包和脚本解释器,shell命令行就是系统必备的脚本解释器。
17 程序开发中,使用调试器单步调试,或使用字符串调试信息,输出"函数的参数信息"和"函数的输出结果信息",从而对一个功能函数或功能模块进行调试。而在shell script中,可以使用命令行,就像一个单步调试的功能利器,显示程序的参数和输出结果,调试时不需要所有代码运行。调试好一个命令行程序的功能后,copy到脚本程序中即可。以这种方法调试一个功能函数,尤其是不常用,或不熟悉的函数/命令,应该比其它编程语言要便利。
18 例如:我们对图形编程不是很熟悉时,创建一个窗体的函数使用时,需浏览帮助文档,单步调试。而脚本程序使用zenity创建一个常用的窗体时,我们使用程序的帮助文档,在命令行调试zenity创建窗体的功能,可用之后在脚本中运行。相比而言,脚本程序不需要编译器,不需要调试软件,即可使用命令行调试一个功能。
19 脚本函数的库和中间件,使用命令行程序。例如一个gui程序,使用gui编程,可使用gdialog。将gdialog命令实现的功能,封装成脚本函数库,便于使用。
20 使用shell脚本库,用于一些功能稍微多一些的脚本程序,使得shell脚本能更好的用于应用程序的编写。
24 shlib-lite中的库文件耦合性相对较小,库文件和库文件之间的依赖关系较少,可单个库文件copy使用,这样就不需要安装整个shlib-lite。或者从库文件中copy一部分代码,或者将库文件当作一份参考文档进行使用。shell脚本函数的运行效率不高,有时将函数中的代码copy到自己的代码中,或参照程序的使用方法,相对会省cpu资源些。以copy代码的方式使用,是对shlib-lite的代码有一定的了解的使用,也更希望开发者能对代码有一定理解后使用,这样使用更容易了解shlib-lite某个功能函数编写时的思路。最佳的情况是,shlib-lite就像是开发者自己编写的代码库一样。同时,这样的使用形式,也更容易使shlib-lite能活跃于开发者人群中,不至于沉没于众多日新月异的开发资源中。因为自己的代码,通常有自己的使用习惯,不容易忘记。
25 在使用shlib-lite时,不仅仅是使用lib库,也是程序开发者在编写脚本的过程中,遇到的问题的处理方法的一个集合,或者笔记。即便是没有shlib-lite,很多开发者或许也会将一些比较有用的功能,以code-piece的方式,保存在某个笔记文件中。shlib-lite是一份shell脚本编程时,常用功能的文档,是一些易错功能的补充,当然,以库函数的形式供程序开发者使用。
26 其它shlib或许更多的应该是以函数接口的方式使用,而不一定需要copy代码,阅读代码的方式使用。函数库的意义不就是用户根据功能和接口函数进行使用吗?如果都以阅读代码的方式使用,那就成了一份参考文档。shlib-lite的功能更基础一些,或许与通常的脚本编写的习惯也有所不同。
30 shlib-lite的功能比较简略,但是比较基础,是使用其它shlib库的基础。例如使用shlib库需要在脚本开头使用". shlibinc",才能在后面使用include xxx.shlib包含一个函数库。否则程序中只能以shlib库文件实际存放的,固定的文件路径进行source使用。
31 例如stdio.shlib中的input函数,通常read命令在使用时默认对\进行过滤,且以空格作为变量输入的分隔符,这对于需要输入一个带空格的常用字符串来说,读取不到输入的字符串。
32 在shlib中,一些函数是作为功能库,而有一些函数或功能是改变脚本程序使用形式的,使得shell编程从命令行的批处理脚本编程,更接近c语言等程序开发语言的编程习惯。
33 + shlibinc和include,用于包含库文件。相比source使用完整的文件路径,shlib可以将库文件放在/usr/shlib,或是/usr/local/shlib目录下,包含文件时会自动从指定目录列表中使用对应的库。
34 + func用于带参数名称的函数的定义,在使用dvar时还可以设置参数变量的类型。对于脚本开发不是必不可少的,但是提供一种形式,比$1这样的参数更直观些。另外,在dvar中用于设置带类型的参数,便于不同编程语言之间的函数调用。
35 + namespace的使用,对函数和变量进行分类存放。在命令行程序越来越多,函数也越来越多的情况下,命令行命令和脚本程序函数名称,成了一种有限的资源。在程序语言中的namespace就是用于处理这个问题的。在shlib-lite中只是以函数的形式扩展这个功能,不完全等同与编程语言中namespace的使用(该功能尚未编写代码)。
36 + 使用shlib-lite编写的dvar,又是一种对shell脚本编程的扩展,它使得shell脚本可以和其它编程语言一样,可以使用带类型的变量,可以使用结构体类型定义,可以关联数据类型到内存数据块,或文件数据块。还可以对树形结构的变量/数据的组织。dvar中包含了常用的数据结构类型。(该功能在另一个软件包dvar-shlib或dvar中实现,代码尚未编写好)。
37 + vqstack队列和堆栈的使用。通常脚本中的变量都是单个使用的,以一个队列或堆栈进行使用,使得程序功能编写比较容易些,更接近其它编程语言的使用风格。
38 + stdio、term、dbgout等库文件,可使用不同的输出通道输出字符串信息,包含彩色显示和光标移动等丰富的输入输出功能,格式化的日志/调试信息输出,可使用程序对日志进行解析,在调试信息比较多时用程序过滤一部分信息。
39 + args使用"参数描述字符串"编写参数信息,shlib库将参数自动解析成环境变量,并调用对应的参数处理函数。在程序编写usage函数输出helper信息时,自动生成输出字符串,避免功能编写和helper信息之间的不同步。
40 + imifile使得程序可以用ini文件作为参数配置,并可设置保存这些参数。可将ini文件中的参数定义成变量,程序使用时不需要字符串处理。imi是在ini基础上增加一些功能的参数config文件。
41 + shellprog将常用的库文件包含在一起,包括args、func、stdio、term、dbgout、inifile、cmdmenu等,这样基本包含了一个程序需要的常用功能。适用于编写命令行程序和daemon程序。
42 + fix-shebang用于调整脚本文件中的脚本解释器及路径。
43 + scripttest程序不是一个库文件,它使用目录结构的文本文件,建立一系列测试用例,并逐个运行进行测试。
44 这些功能部分有别于通常的脚本编程,但在程序开发中比较便捷。
45 shlib-lite和dvar一同构建的是shell脚本编程的语言基础,以命令行程序,以及各种shlib作为shell脚本编程的功能基础,使得sh脚本的使用更容易,且接近编译型程序语言的使用。
49 最初的shlib源自于dvar程序的开发。shlib-lite中,scripttest就是一个基于shlib-lite开发的测试管理程序。
50 shellprog中包含了一个程序编写的常用功能。可以用来编写命令行程序,也可以是daemon程序。搭配上其它应用功能性的shlib库,可以方便的开发各种应用程序。像是网络通信的程序,tui或gui界面的人机交互程序,或者搭配硬件操作的程序,用于嵌入式程序开发的一部分,或者用于开发IoT的应用。
52 脚本程序的运行效率不高,一些运算型的应用不是很合适,应该由可执行程序和脚本搭配使用。脚本构建一个程序,比c/c++相对容易些,它不需要编译器,运行环境是通用的shell命令行。一些功能以命令行程序的形式使用,比重新编写代码实现功能省事些。对于c/c++开发者来说实现的一个繁琐的结构体和代码,或许在脚本程序中以通用的字符串处理程序即可实现。
53 args中的参数描述字符串就是一个例子。在c语言中,或许笔者能想到的首选的方法,就是以一个结构体去描述参数信息,进行程序处理。脚本语言的使用,尤其是字符串处理的应用,对c/c++开发者应该会有不同的程序思路。
57 shell脚本的一个不足是运行效率不高,比较费cpu资源。在shlib-lite编写时也对程序进行调整。args解析参数虽然比较容易,但程序初始化时会卡一下。于是添加了--insert-helper(尚未编写代码),用于将模式字符串解析后的环境变量放置到用户程序中,减少运行时间。
58 shlib-lite一直在一款最高主频不到2GHz的quard-core的安卓pad上进行开发。pad的电源管理程序通常只使用2个cpu,且为了省电,主频应该只有几百兆(笔者根据运行速度估的)。
60 这样程序库可以用在一些处理器性能不高的工业级芯片的处理器上运行。对于pc和服务器有较多的软件可使用,各类资源比较丰富。而嵌入式应用中,c/c++编程的开发环境,工程的构建都不是一个入门级newer所适用的。其它的脚本语言功能比较丰富,但对于资源不多的一些场合,脚本解释器内存资源和cpu资源都不低,或许和shell脚本半斤八两。而且需要一些程序库。脚本程序有天然的shell程序和命令行。入门难度更低一些。相比于其它脚本操作硬件接口时,使用的c语言编写的程序,需要一个newer去学习和了解。而shell可使用命令行程序,而不是接口函数。硬件功能的使用,通常也需要硬件程序用于基本的功能验证和使用,与shell脚本搭配使用,比较容易。
61 例如,内核对spi接口的驱动程序提供了spi_test,对i2c接口的驱动程序提供了i2c-tools软件包。两个应用软件提供的是硬件接口的使用,开发者只需要将硬件接口测试时所使用的命令写到一个shell脚本,即可实现一些硬件的功能。
62 例如使用一个iic接口的温度传感器,可以使用i2cset的参数设置设备的地址,硬件设备从i2c接口返回数据,由i2cset程序读取,并以16进制数据在命令行输出。通常一个硬件接口就是可用的了。shell脚本用于解析字符串数据,生成用户需要的温度值。这个过程通常是硬件和硬件测试程序,以及命令行的堆砌,用于实现硬件相关的某一个功能。
63 当你使用的是一个功能相对多一些,寄存器值也比较多的情况下,有多个对应的命令行脚本进行测试和使用。如果使用shell程序,将这些单个功能的脚本编写成函数,就是某一个硬件的功能函数库。如果需要对这些功能逐个测试,不觉得命令行菜单输出功能类型的字符串更加方便吗?