shell环境

原创
2016/11/26 22:39
阅读数 127

一、命令行参数

    当一个新的进程执行时,命令行参数和环境变量是两个非常重要的信息。这两个信息是新进程从产生它的父进程那里获得,其获得方式不同。命令行参数作为main函数的参数被传到新进程中,而环境变量是作为一种全局变量被新进程所使用的。

对于C语言来说,程序从main函数开始执行:

int main(int argc, char * argv[]);

其中argc是命令行参数的个数,argv是指向参数的各个指针所构成的数组,其每一个元素是一个字符串,以'\0'结尾,代表一个命令行参数。

如下程序:

#include <stdio.h>

int main(int argc, char *argv[])
{
  int i;
  printf("count of arguments: %d\n", argc);
  for(i = 0; i< argc; i++)
    {
      printf("argv[%d]: %s\n", i, argv[i]);
    }
  
  return 0;
}

程序运行结果:

得到程序文件名

    命令行参数的第一个(argv[0])是程序的路径名,并不是该程序的文件名。需要对其进行一些处理:

#include <stdio.h>
#include <string.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("full file name is : %s\n", argv[0]);
  printf("file name is : %s\n", p);
  
  return 0;
}

运行结果:

注意:argv[argc]是一个NULL指针,这一点不会由机器自动完成,但是此定义遵守ISO C。

 

二、环境变量

环境变量和命令行参数情况有所不同。每个程序都会有一个环境变量表,和命令行参数表一样,环境变量表也是一个指针数组。

extern char **envrion;

每一个环境变量的表示形式为:

环境变量=环境变量值(最后有一个'\0'结束符)

环境表就是由若干个这种字符串构成的,最后由一个NULL指针最为结束标志。

#include <stdio.h>

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

int main(int argc, char *argv[])
{
  int i;

  //遍历打印环境变量,但是这种方法并不推荐
  for(i = 0; environ[i] != NULL; i++)
    {
      printf("each: %s\n", environ[i]);
    }
  return 0;
}

程序运行如下:

程序会打印出很多环境变量,这些环境变量是从调用exec()函数创建该进程的shell中继承得来的。

  • 命令行参数需要程序编写者手动传递给新的进程。环境变量的获取是由操作系统自动完成的,在引用的时候只需声明外部变量environ就可以了。
  • 命令行参数可以人为输入。环境变量只能从调用exec()函数的进程那里继承而来,而且在本进程中修改环境变量不会影响其它进程。

 

三、得到指定的环境变量

    环境变量是一个字符串数组,通过environ指针来访问其元素就是一个例子。但是这种方法是不推荐的。这里介绍推荐的访问环境变量的办法。linux下使用getenv()函数得到一个环境变量,其函数原型如下:

#include <stdlib.h>
char *getenv(const char *name);

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

下面例子演示了得到一个环境变量:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
  char *p;
  p = getenv("HOME");  //得到环境变量HOME的值
  if(p == NULL) {
    perror("fail to get env");
    exit(1);
  }
  printf("$HOME id %s\n", p);
  
  return 0;
}

输出结果为:

 

四、设置一个环境变量

    Linux系统允许用户设置一个环境变量的值,当该环境变量已经有值时,还可以将其替换。如果添加的环境变量尚未存在于环境变量表中时,系统会为用户添加这个环境变量。

1.putenv()函数

Linux环境下使用putenv()函数对一个环境变量赋值,其函数原型如下:

#include <stdlib.h>
int putenv(char *envvar);

putenv()函数将一个形如name=value的字符串放进环境表。该函数也可以用来添加一个以前不存在的环境变量,如果成功堆环境变量赋值,则putenv()函数返回0,如失败返回-1.

下面的示例演示了对一个环境变量的赋值:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
  char *p;
  p = getenv("HOME");    //得到环境变量
  if(p == NULL) {
    perror("fail to getenv");
    exit(1);
  }
  printf("$HOME is %s\n", p);  //输出环境变量

  if(putenv("HOME=/home/admin") == -1) {  //修改环境变量HOME的值
    perror("fail to putenv");
    exit(1);
  }

  p = getenv("HOME");
  if(p == NULL) {
    perror("fail to getenv");
    exit(1);
  }
  printf("$HOME is %s\n", p);  //再次输出环境变量

  if(putenv("ADMIN=hello") == -1) {  //添加一个没有的环境变量
    perror("fail to putenv");
    exit(1);
  }
  p = getenv("ADMIN");
  if(p == NULL) {
    perror("fail to getenv");
    exit(1);
  }
  printf("ADMIN is %s\n", p);
  
  return 0;
}

运行结果为:

2.setenv()函数

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

#include <stdlib.h>
int setenv(const char *name, const char *value, int rewrite);

setenv()函数第1个参数代表要进行赋值的环境变量的名称,第2个参数代表该环境变量的新值。第3个参数很重要,其决定是否覆盖已经存在的环境变量的值。如果rewrite值为0,则不修改原来的值,如果rewrite值非0,则修改原来的值。如果成功对环境变量赋值,则setenv()函数返回0,失败则返回-1.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
  char *p;
  p = getenv("HOME");
  if(p == NULL) {
    perror("fail to getenv");
    exit(1);
  }
  printf("$HOME is %s\n", p);

  //第一次设置环境变量HOME的值,不改变原来的值
  if(setenv("HOME", "/home/admin", 0) == -1) {
    perror("fail to setenv");
    exit(1);
  }

  p = getenv("HOME");
  if(p == NULL) {
    perror("fail to getenv");
    exit(1);
  }
  printf("$HOME is %s\n", p);

  //第2次设置环境变量HOME的值,改变原来的值
  if(setenv("HOME", "/home/admin", 1) == -1) {
    perror("fail to setenv");
    exit(1);
  }

  p = getenv("HOME");
  if(p == NULL) {
    perror("fail to getenv");
    exit(1);
  }
  printf("$HOME is %s\n", p);
  return 0;
}

运行结果为:

3.unsetenv()

Linux下使用unsetenv()函数删除一个环境变量的值,其函数原型如下:

#include <stdlib.h>
int unsetenv(const char *name);

第1个参数表示要删除的环境变量的名称,即使name代表的环境变量病不存在也不会出错。

4.clearenv()

Linux下使用clearenv()函数清除环境表中的所有环境变量,其函数原型如下:

#include <stdlib.h>
int clearenv();

clearenv()函数将环境变量连同值一起删除,而且连environ这个指针都会置为NULL,撤销整个环境表。由此可见,此函数应该慎用。

下面演示此函数的使用:

#include <stdio.h>
#include <stdlib.h>

extern **environ;

int main(int argc, char *argv[])
{
  if(clearenv() == -1) {
    perror("fail to clearenv");
    exit(1);
  }
  if(environ == NULL) {
    printf("done\n");
  }
  return 0;
}

运行结果为:

注意:以上对环境变量的操作只能影响到操作进程和子进程,对其父进程没有影响。

 

四、得到进程结束状态

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

$运行程序
$echo $?

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

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

用一个示例测试一下:

#include <stdio.h>

int main(int argc, char *argv[])
{
  printf("hello\n");
  return 4;
}

运行程序:

 

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部