Linux进程操作(进程环境--shell环境)

shell环境

命令行参数

  • 概念:当一个新的进程执行时,命令行参数环境变量是两个非常重要的信息。这两个信息都是新进程从产生它的父进程那里获得的,其获得方式也不相同。命令行参数作为main函数的参数被传到新进程中,而环境变量是作为一种全局变量被新进程所使用的。
  • 对于C来说,程序的执行从main函数开始,其中argc是命令行参数的个数,argv 是指向参数的各个指针所构成的数组,其每一个元素是一个字符串,以‘\0’结尾, 代表一个命令行参数。执行一个程序时,调用exec函数的进程会把命令行参数传递给新程序。
int main(int argc,char* argv[]);

得到程序文件名

  • 命令行参数的第一个(argv[0])是程序的路径名,并不是程序文件名,如果希望在程序中使用该程序文件名,则需要做特殊处理。
  • 自己实现 basename 函数,可以从argv[0]这个参数中提取该文件的文件名,当然编译的时候名字要和文件名一样哟!
#include<stdio.h>

/*得到一个完整路径中的最后的文件名*/
char* basename(char* full_name){
	
	char* p;
	p=rindex(full_name,'/');//找到路径名中最后一个'/'
	if(p=='\0')
		p=full_name;
	else
		p++;
	return p;
}

int main(int argc,char* argv[]){
	
	char* p;
	p=basename(argv[0]);
	printf("file name is:%s\n",p);
	return 0;
}
  • 注意:
    在这里插入图片描述

环境变量

  • 概念: 环境变量和命令行参数情况有所不同。每个程序都会有一个环境变量表,和命令行参数表一样,环境变量表也是一个指针数组。
extern char ** environ;
  • 进程中环境变量示意图
    在这里插入图片描述
  • 环境变量的表示:环境变量名=环境变量值(最后有一个’\0’结束符);环境表就是由若干个这种字符串构成的,最后由一个NULL指针作为结束标志,下面代码演示了打印进程的环境变量,这种遍历环境变量的方法不推荐使用, 原因跟C程序的存储布局有关。
#include<stdio.h>

extern ** environ;//环境变量表的指针

int main(){
	
	int i;
	for(i=0;environ[i] != NULL;i++)
		printf("each:%s\n",environ[i]);
	return 0;
}

得到指定的环境变量

Linux使用getenv函数得到一个环境变量的值,函数原型为:

#include<stdlib.h>

char* getenv(const char* name);
  • 参数说明:getenv函数的参数代表指定的环境变量的名称,该函数寻找一一个形如name=value的字符串,将value字符串的内容作为环境变量的值返回。如果成功,getenv函数返回该环境变量值字符串的首地址,失败则返回NUlL.

设置一个环境变量

putenv: Linux系统允许用户设置一个环境变量的值,当该环境变量已经有值时,还可以将其替换。Linux环境下使用 putenv函数对一个环境变量赋值,其函数原型如下:

#include<stdlib.h>
int putenv(char *str);
  • 参数说明:putenv函数将一个形如 name=value 的字符串放进环境表,如果原来有值则替换原来的环境变量值。该函数也可以用来添加一个以前不存在的环境变量,如果成功对环境变量赋值,则putenv函数返回0,失败返回-1。

setenv: 也可以使用setenv函数对环境变量赋值,其函数原型如下:

#include<stdlib.h>
int setenv(const char* name,const char* value,int rewrite);
  • 参数说明:setenv函数第1个参数代表要进行赋值的环境变量的名称,第2个参数代表该环境变量的新值。第3个参数很重要,其决定是否覆盖已经存在的环境变量的值。如果rewrite 值为0,则不修改原来的值,rewrite 值非0,则修改原来的值。如果成功对环境变量赋值,函数返回0,失败则返回-1。

unsetenv: Linux使用此函数删除一个环境变量的值,函数原型为:

#include<stdio.h>
#include<stdlib.h>
int unsetenv(const char* name);
  • 参数说明:unsetenv的第1个参数表示要删除的环境变量的名称,即使name所代表的环境变量并不存在也不会出错。如果成功删除环境变量的值,unsetenv 函数返回0,失败则返回-1。

clearenv:清除所有环境表中的变量,函数原型如下:

#include<stdlib.h>
int clearenv();
  • 参数说明:clearenv函数将环境变量连同值一起删除,而且连environ这个指针都会置为NULL,撤销整个环境表。由此可见,对于此函数应该慎用。如果成功删除所有的环境变量,clearenv函数返回0,失败则返回-1。

注意: 以上对环境变量的操作只能影响到操作进程和子进程,对其父进程没有影响。这是合理的,试想一下,-一个shell产生一个执行命令的子进程更改了自己的环境,如果能够影响到父进程的话,那么以后shell在产生的所有执行命令的子进程都要受到这个子进程的影响,这显然是不安全的。

得到进程结束状态

Linux可以通过shell得到已结束的进程的结束状态;

$echo $?

说明:$?是linux shell中的一个内置变量,其中保存的是最近一次运行的进程的返回值,这个返回值有以下三种情况:

  • 程序中的main函数运行结束,$?中保存main函数的返回值。
  • 程序运行中调用exit函数结束运行,$?中保存exit函数的参数。
  • 程序异常退出,$?中保存异常出错的错误号。

注意: 首先shell内置变量保存的是最近一次运行的进程的返回值,所以使用时要确保在打印需要的进程返回值前不要有其他的操作,同时应该避免后台进程的骚扰。其次在运行程序时如果程序运行出错,例如shell 找不到指定的进程,那么$?内置变量中的值是1。

使用errno调试程序

调试程序的方法:

  • 使用调试器;
  • 在程序中直接使用输出函数输出调试信息;
  • 查看标准输出;
  • 程序异常时所写的日志。

errno: 养成良好的调试习惯。对于提高开发效率观是很有帮助的。C语言提供了一个全局变量----errno,很好的弥补了Linux系统调用返回值信息不足的缺点。大多数Linux 系统调用再出错时都会操作此变量,将其置为一个特定值,输出这个变量的值开发者就可以知道系统调用失败的原因,从而正确的排除错误。errno是一个整形变量,定义在errno.c,声明在errno.h

  • **注意:**因为ermo是一个全局变量所以该程序中所有调用的系统调用都会修改它的值,为了不让上一次的错误值影响这–次的判断,在使用ermo变量前要将其清零。

输出错误原因

Linux提供两个函数可以完成错误号到错误文字描述的转换:strerror 和 perror

  • strerror:: 根据错误号返回错误的描述
#include<string.h>
char* strerror(int err);

参数说明: err 就是errno的值

  • perror: 根据全局变量 errmo 和传入的字符串,打印一条出错信息.
#include<stdio.h>
#include<errno.h>

void perror(const char* pszInfo);

参数说明:perror的參数表示要输出的字符串,系统自动将使用 errno 变量映射得到的错误文件描述的字符串连接在参数字符串的后面。该字符串不需要添加‘\n’,perror函数会自动添加,perror函数没有返回值。

#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<unistd.h>
#include<errno.h>

int main(){

	int fd;
	errno=0;

	fd=open("tt.txt",O_RDWR);
	if(-1 == fd){
		perror("fail to open");
		exit(1);
	}
	close(fd);
	return 0;
}
//运行结果:
fail to open: No such file or directory
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值