linux程序设计——linux环境(第四章)

linux环境

这篇为linux环境,代码在linux环境代码下载。当为linux编写程序时,必须考虑到程序将在一个多任务环境中运行。这意味着在同一时间会有多个程序运行,它们共享内存、磁盘空间和CPU周期等机器资源。甚至同一程序也会有多个实例同时运行。最重要的是,这些程序能够互不干扰,能够了解它们的环境,并且能够正确运行,不产生冲突。
这章介绍程序运行的环境,程序如何通过环境来获得有关其运行条件的信息,以及用户怎样改变程序的行为。

4.1 程序参数

当一个用C语言编写的linux程序运行时,它是从main函数开始的,对这些程序而言,main函数的声明如下所示:
int main(int argc, char *argv[])
其中argc是程序参数的个数,argv是一个代表参数自身的字符串数组
也可以简单的声明为:
main()
因为默认的返回值类型是int,而且函数中不用的形式参数不需要声明。argc和argv仍在,但是如果不声明它们,就不能使用它们。
无论操作系统何时启动一个新程序,参数argc和argv都被设置并传递给main,这些参数通常由另一个程序提供,这个程序一般是shell,它要求操作系统启动该新程序。shell接受用户输入的命令行,将命令行分解成单词,然后这些单词放入argv数组。
例如,如果我们给shell输入以下命令:
myprog left right ‘and center‘
程序prog将从main函数开始,main带的参数是:
argc:4
argv:{"myprog", "left", "right", "and center"}
注意,参数个数包括程序名自身,argv数组包含程序名,并将它作为第一个元素argv[0]。因为shell命令里使用了引号,所以第四个参数是一个包含了空格的字符串。
命令行参数在向程序传递信息方面是很有用的。例如,我们可以在一个数据库应用程序中使用命令行参数传递想用的数据库的名字,这样就可以在多个数据库上使用同一个程序。许多工具程序也使用命令行参数来改变程序的行为或者设置选项。通常可以使用一个短横线-开头的命令行参数来设置这些所谓的命令或者开关。例如,sort程序可以用一个开关来进行逆向排序:
sort -r file
编写程序argc.c对参数进行检查。

4.1.1 getopt

linux提供getopt函数,它支持需要关联值和不需要关联值的选项。
#include <unistd.h>
int getopt(int argc, char *const argv[], const char *optstring);
extern char *optarg;
extern int optind, opterr, optopt;
getopt函数将传递给程序的main函数的argc和argv作为参数,同时接受一个选项指定字符串optstring,该字符串告诉getopt哪些选项可用,以及它们是否有关联值。optstring只有一个字符列表,每个字符代表一个单字符选项。如果一个字符后面紧跟着一个冒号:,则表明该选项有一个关联值作为下一个参数。
例如,我们可以通过下面的调用来处理上面的例子:
getopt(argc, argv, "if:lr");
它允许几个简单的选项:-i,-l,-r和-f,其中-f选项后要紧跟着一个文件名参数。使用相同的参数,但以不同的顺序来调用命令将改变程序的行为。
getopt的返回值是argv数组中的下一选项字符。
getopt有如下行为:
如果选项有一个关联值,则外部变量optarg指向这个值。
如果选项处理完毕,getopt返回-1,特殊参数--将使getopt停止扫描选项。
如果遇到一个无法识别的选项,getopt返回一个问号,并把它保存到外部变量optopt中。
如果一个选项要求有一个关联值,但是用户并未提供这个值,getopt通常将返回一个问号。
编写程序argopt.c

4.1.2 getopt_long

GNU C函数包含getopt的另一个版本,称为getopt_long,它接受以双划线--开始的长参数。
可以使用getopt_long创建一个新版本的示例程序,它可以使用与前面选项等效的长参数选项:
./longopt --initialize --list ‘hi there‘ --file fred.c -q
编写程序longopt.c

4.2    环境变量

环境变量是用来控制shell脚本和其他程序行为的变量,可以用它们来配置用户环境。例如,每个用户有一个环境变量HOME,它定义了用户的家目录,即该用户会话的默认开始位置。
echo $HOME
UNIX规范为各种应用定义了许多标准环境变量,包括终端类型、默认的编辑器、时区等。C语言可以通过putenv和getenv函数来访问环境变量:
#include <stdlib.h>
char* getenv(const char* name);
int putenv(const char* string);
环境由一组格式为"名字=值"的字符串组成。getenv函数以给定的名字搜索环境中的一个字符串,并返回与改名字相关的值。如果请求的变量不存在,它就返回null。由于getenv返回的字符串是存储在getenv提供的静态空间中,所以如果想进一步使用它,就必须将它复制到另一个字符串中,以免它被后续的getenv调用所覆盖。
putenv函数以一个格式为"名字=值"的字符串作为参数,并将该字符串加到当前环境中。如果由于可用内存不足而不能扩展环境,它会失败并返回-1.
编写程序environ.c
注意:环境仅对程序本身有效,在程序里做的改变不会反映到外部环境中,这是因为变量的值不会从子进程(程序)传播到父进程(shell)

4.2.1 环境变量的用途

程序经常使用环境变量来改变它们的工作方式。用户可以通过以下方式设置环境变量的值:在默认环境中设置、通过登录shell读取的.profile文件来设置、使用shell专用的启动文件(rc)或在shell命令行上对变量进行设定。例如:
./environ.exe fred
fred=hello ./environ fred
shell将行首的变量赋值作为对环境变量的临时改变。

4.2.2 environ变量

程序的环境由一组格式为"名字=值"的字符串组成。程序可以通过environ变量直接访问这个字符串数组。environ变量的声明如下所示:
#include <stdlib.h>
extern char** environ;

4.3    时间和日期

通常能确定时间和日期对一个程序来说是非常有用的。程序可能希望记录它运行的时间,或者可能需要在某些时候改变它的运行方式。
时间通过一个预定义的类型time_t来处理。这是一个大到能够容纳以秒计算的日期和时间的整数类型。
#include <time.h>
time_t time(time_t *tloc);
可以通过调用time函数得到底层的时间值,它返回的是从纪元开始至今的秒数。如果tloc不是一个空指针,time函数还会把返回值写入tloc指针指向的位置
编写程序envtime.c
函数difftime用来计算两个time_t值之间的秒数并以double类型返回它
#include <time.h>
double difftime(time_t time1, time_t time2);
difftime函数计算两个时间值之间的差,并将time1-time2的值作为浮点数返回。
gmtime函数把底层时间值分解为一个结构,该结构包含一些常用的成员:
#include <time.h>
struct tm *gmtime(const time_t timeval);
如果要看当地时间,需要使用localtime函数。
#include <time.h>
struct tm *localtime(const time_t *timeval);
localtime函数和gmtime一样,除了它返回的结构中包含的值已根据当地时区和是否采用夏令时做了调整。
为了得到更"友好"的时间和日期表示,像date命令输出的那样,可以使用asctime函数和ctime函数:
#include <time.h>
char *asctime(const struct tm *timeptr);
char *ctime(const time_t *timeval);
asctime函数返回一个字符串,它表示由tm结构timeptr所给出的时间和日期。这个返回的字符串有类似下面的格式:
Mon Jun  8 16:23:05 2015

4.4    临时文件

很多情况下,程序会利用一些文件形式的临时存储手段。这些临时文件可能保存着一个计算的中间结果,也可能是关键操作前的文件备份。
临时文件的缺点是必须确保应用程序为临时文件选取的文件名是唯一的。
用tmpnam函数可以生成一个唯一的文件名。
#include <stdio.h>
char *tmpnam(char *s);
如果遇到需要立刻使用临时文件的情况,可以用tmpfile函数在给它命名的同时打开它。
#include <stdio.h>
FILE* tmpfile(void);
tmpfile函数返回一个文件流指针,它指向一个唯一的临时文件。该文件以读写方式打开,当对它的所有引用全部关闭时,该文件会自动被删除。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。