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函数返回一个文件流指针,它指向一个唯一的临时文件。该文件以读写方式打开,当对它的所有引用全部关闭时,该文件会自动被删除。

时间: 2024-08-29 10:07:34

linux程序设计——linux环境(第四章)的相关文章

Linux与云计算——第二阶段 第四章:DNS服务器架设1-安装BIND

Linux与云计算--第二阶段Linux服务器架设 第四章:DNS服务器架设1-DNS基础原理和软件包安装 一般来讲域名比IP地址更加的有含义.也更容易记住,所以通常用户更习惯输入域名来访问网络中的资源,但是计算机主机在互联网中只能通过IP识别对方主机,那么就需要DNS域名解析服务了. DNS域名解析服务(Domain Name System)是用于解析域名与IP地址对应关系的服务,功能上可以实现正向解析与反向解析: 正向解析:根据主机名(域名)查找对应的IP地址. 反向解析:根据IP地址查找对

《Linux Device Drivers》第四章 调试技术——note

1.本章知识点 内核中和调试相关的选项 CONFIG_DEBUG_KERNEL CONFIG_DEBUG_SLAB CONFIG_DEBUG_PAGEALLOC CONFIG_DEBUG_SPINLOCK CONFIG_DEBUG_SPINLOCK_SLEEP CONFIG_INIT_DEBUG CONFIG_DEBUG_INFO CONFIG_MAGIC_SYSRQ CONFIG_DEBUG_STACKOVERFLOW CONFIG_DEBUG_STACK_USAGE CONFIG_KALLS

Java语言程序设计(基础篇) 第四章 数学函数、字符和字符串

第四章 数学函数.字符和字符串 4.2 常用数学函数 方法分三类:三角函数方法(trigonometric method).指数函数方法(exponent method)和服务方法(service method) 4.4 String类型 String类型不是基本类型,而是引用类型(reference type).

JavaScript高级程序设计:第十四章

第十四章 一.表单的基础知识 在HTML中,表单是由<form>元素来表示的,而在javascript中,表单对应的则是HTMLFormElement类型.HTMLFormElement继承了HTMLElement,因而与其他HTML元素具有相同的默认属性.不过,HTMLFormElement也有它自己下列独有的属性和方法. 取得<form>元素的引用方式有好几种.其中最常见的方式就是将它看成与其他元素一样,并为其添加id特性,然后再像下面这样使用getElementById()方

linux程序设计——数据管理(第七章)

第七章    数据管理 7.1    内存管理 这篇为linux的内存管理,代码在内存管理代码下载.在所有计算机系统中,内存都是一种稀缺资源.linux为应用程序提供了一个简洁的视图,它能反映一个巨大的可直接寻址的内存空间,此外,linux还提供了内存保护机制,它避免了不同的应用程序之间的互相干扰.如果机器被正确配置并且有足够的交换空间,linux还允许应用程序访问比实际物理内存更大的内存空间. 7.1.1 简单的内存分配 使用标准C语言函数库中的malloc调用来分配内存: #include

linux程序设计——数据库(第七章)

7.3 数据库 这篇为linux的dbm数据库,代码在dbm数据库代码下载.可以使用文件来存储数据,为什么还需要数据库呢?因为在有些情况下,数据库的特性提供了解决问题的更好的办法.与使用文件来存储数据相比,使用数据库有如下两方面的优势: 1.可以存储长度可变的数据记录,这对平面的.非结构化的文件来说实现起来有点困难 2.数据库使用索引来有效地存储和检索数据.这样做的一个显著优点是这个索引不必要非得是一个简单的记录号--这在平面文件中很容易实现,它可以是一个任意的字符串. 7.3.1 dbm数据库

鸟0哥的Linux私房菜——第十四章:Bash Shell

视频链接 土豆: B站: 本章目录: 1. Bash shell1.1 什么是 shell ? (我们通过shell与Kernel核心沟通,使Kernel操控硬件)1.2 系统的 shell 与 /etc/shells 功能 (cat /etc/shells一下,可以看到当前电脑的shell)1.3 Bash shell 的功能  (1.命令编修能力,就是记忆你写的命令按上下键切换.2.命令与档案补全功能,就是tab键补全.3.命令别名(alias)设定功能alias命令.下面还有一些介绍)1.

【linux程序设计4th】第三章1

makefile .PHONY:clean all CC=gcc CFLAGS=-Wall -g ###replace your bin BIN=simple_write simple_read copy_system all:$(BIN) %.o:%.c $(CC) $(CFLAGS) -c $< -o [email protected] clean: rm -f *.o $(BIN) simple_write.c /* #include <unistd.h> ssize_t writ

linux命令行大全-第四章【文件操作mkdir cp mv rm ln】

pwd:显示当前目录 date:显示当前日期 cal:显示日历 ls:列出目录内容 cd:改变当前工作目录 ‘.’:代表工作目录 ‘..’:代表工作目录父目录 进入当前目录的父目录:cd /home 和 cd .. 进入当前目录的子目录:cd jeremy 和 cd ./jeremy 1.创建一个目录:mkdir playground 2.进入该目录:cd playground (也可以使用cd ./playground) 3.创建两个子目录:mkdir dir1 dir2 (目录下创建好了两个