相信对看了前面几节内容的朋友来说,在 linux 中开发 C语言程序已经不在话下了。不过,不知道大家注意到没,我们自己写的C语言程序编译后,要想在 shell 中执行,往往还要将可执行程序的路径也输入。
执行自定义的C语言程序,需要输入路径
例如,C语言程序编译后的可执行文件名是 a.out,要想执行它,需要输入的命令是
# ./a.out
./ 表示当前路径。如果直接输入 a.out,是会报错的
# a.out
a.out: command not found
明明当前目录下有 a.out 这个文件,系统却提示“command not found(无法找到命令)”。而执行常用的 ls、gcc 等命令却不用输入路径,这是为什么呢?
linux 中的环境变量
按照百科上的解释,环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数,如:临时文件夹位置和系统文件夹位置等。linux 操作系统中有很多种环境变量,常用的有
- PATH,shell 寻找命令和程序的目录集。
- LD_LIBRARY_PATH,程序执行时,会到这个环境变量记录的目录里寻找链接库。
- HOME, 当前用户主目录。
- SHELL,当前用户 shell 类型
等等。linux 操作系统中的目录非常多,查找命令和程序时,不可能遍历所有目录,不然就太低效了。所以,linux 使用 PATH 环境变量记录若干目录,在用户输入不带路径的命令时,只去这些目录查询,这样就避免了遍历所有目录导致的系统响应缓慢。
在 linux 中可以使用 echo 命令查看环境变量。例如若查询 PATH 环境变量,可以输入:
# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
可以看出,PATH 环境变量记录了若干目录,这些目录之间使用“:”隔开。用户输入不带路径的命令时,linux 只会去这些目录查找,如果找不到就会报错:“command not found”。
现在查看以下 a.out 的路径:
# ls
a.out cscope.files cscope.out his sim.out t2.c t3.c t4.c t6.c t.c testparamfun.c test.txt
# pwd
/lccRoot/C/tmp
果然不在 PATH 记录的目录里面,这就理解为什么只输入 a.out,系统会报错了。
如果希望我们自己编写的C语言程序,能够像 ls、mkdir、touch 等系统命令一样不用输入路径就能执行,可以将 a.out 移到 PATH 记录的那些目录里:
# cp a.out /usr/local/bin
# a.out
hello embedTime
也可以把 a.out 所在目录添加到 PATH 里:
# export PATH=$PATH:/lccRoot/C/tmp
# a.out
hello embedTime
使用 C语言操作环境变量
linux中 C语言提供了 getenv 函数获取环境变量,它的说明手册如下:
getenv 接收一个环境变量名作为参数,返回环境变量值。C语言还提供了 putenv 函数用户设置环境变量:
它接收一个字符串作为参数,成功返回 0,失败返回非 0。参数字符串的格式为
环境变量名=环境变量值
如果环境变量名不存在,则 putenv 函数添加该环境变量。如果环境变量名已经存在,则 putenv 函数修改该环境变量值。现在编写C程序:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *env;
printf("before calling putenv:\n");
env = getenv("PATH");
printf("\tPATH: %s\n", env);
env = getenv("embedTime");
printf("\tembedTime: %s\n", env);
printf("after calling putenv:\n");
putenv("PATH=xxx");
putenv("embedTime=test");
env = getenv("PATH");
printf("\tPATH: %s\n", env);
env = getenv("embedTime");
printf("\tembedTime: %s\n", env);
return 0;
}
程序很简单,先获取 PATH 环境变量,然后尝试获取 embedTime 环境变量,并把获取的结果打印出来。然后使用 putenv 函数重新设置 PATH 和 embedTime 环境变量,再次获取之并打印。编译以上程序,执行得到如下结果:
# gcc test.c
# ./a.out
before calling putenv:
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/lccRoot/C/tmp
embedTime: (null)
after calling putenv:
PATH: xxx
embedTime: test
可以看出,一开始C语言程序成功的获取了 PATH 的值,而 embedTime 并不存在,因此打印出了 NULL。在使用 putenv 函数修改了环境变量之后,PATH 和 embedTime 环境变量都被修改为了指定的值。
嵌入式底层有时也需要接收前端控制发过来的命令,boa 服务和 cgi 程序就是一个不错的选择,而 boa 正是使用环境变量传递 get 和 post 报文的。