【linux草鞋应用编程系列】_2_ 环境变量和进程控制
一、 环境变量
int main(void);
int main(int argc, char* argv[ ]);
int main(int argc, char* argv[ ], char* env[ ] )
#include <stdio.h> int main(int argc,char* argv[], char* env[])
{
int i=; while(env[i])
{
puts(env[i++]);
} return ;
}
程序执行的时候就可以输出所有的环境变量。
#include <stdio.h> extern char** environ; int main(int argc,char* argv[])
{
int i=; while(environ[i])
{
puts(environ[i++]);
} return ;
}
3、获取指定的环境变量
GETENV() Linux Programmer’s Manual GETENV()
NAME
getenv - get an environment variable SYNOPSIS
#include <stdlib.h> char *getenv(const char *name); //要获取的环境变量,比方说传递的是 "HOME" ,将返回HOME的值
UTENV() Linux Programmer’s Manual PUTENV()
NAME
putenv - change or add an environment variable //增加或者改变环境变量的值
SYNOPSIS
#include <stdlib.h> int putenv(char *string); //设置的环境变量字符串, string的格式如下: HOME=/home/volcanol
setenv( ) 和 unsetenv()
SETENV() Linux Programmer’s Manual SETENV()
NAME
setenv - change or add an environment variable //改变或者增加环境变量
SYNOPSIS
#include <stdlib.h> int setenv(const char *name, //要设置的环境变量名;如果不存在就会创建新的环境变量,不管 overwrite的值
const char *value, //要设置的环境变量的值
int overwrite); // 如果环境变量已经存在,当 overwrite非零则改写原值, overwrite=0 则不改变原值 int unsetenv(const char *name); //要删除的环境变量
DESCRIPTION
The setenv() function adds the variable name to the environment with the value
value, if name does not already exist. If name does exist in the environment, then
its value is changed to value if overwrite is non-zero; if overwrite is zero, then
the value of name is not changed. The unsetenv() function deletes the variable name from the environment.
注意:
CLEARENV() CLEARENV()
NAME
clearenv - clear the environment
SYNOPSIS
#include <stdlib.h>
int clearenv(void);
DESCRIPTION
The clearenv() function clears the environment of all name-value pairs and sets the
value of the external variable environ to NULL.
注意这个地方: 没有 linux program manual 的字样,表示这个函数需要慎重使用。
#include <stdio.h>
#include <stdlib.h> int main(int argc,char* argv[])
{
char* env; setenv("Test-env","this is a test env", );
env=getenv("Test-env");
printf("the Test-env is: %s\n ",env); return ;
}
[root@localhost process]# gcc main.c
[root@localhost process]# ./a.out
the Test-env is: this is a test env
[root@localhost process]# ./a.out
the Test-env is:this is a test env
[root@localhost process]# env | grep "test"
[root@localhost process]# env | grep "env"
_=/bin/env
[root@localhost process]#
#include <stdio.h>
#include <stdlib.h> int main(int argc,char* argv[])
{
char* env; /*setenv("Test-env","this is a test env", 1);*/
/*env=getenv("Test-env")*/ putenv("test-env=this is a test env");
env=getenv("test-env");
printf("the test-env is:%s\n",env); unsetenv("test-env");
env=getenv("test-env");
printf("after unsetenv");
printf("the test-env is:%s\n",env); return ;
}
[root@localhost process]# gcc main.c
[root@localhost process]# ./a.out
the test-env is:this is a test env
after unsetenvthe test-env is:(null) //环境变量已经删除
[root@localhost process]#
#include <stdio.h>
#include <stdlib.h> extern char** environ; int main(int argc,char* argv[])
{
int i=;
char* env; /*setenv("Test-env","this is a test env", 1);*/
/*env=getenv("Test-env")*/ putenv("test-env=this is a test env");
env=getenv("test-env");
printf("the test-env is:%s\n",env); unsetenv("test-env");
env=getenv("test-env");
printf("after unsetenv");
printf("the test-env is:%s\n",env); while(environ[i])
{
printf("%s",environ[i++]);
}
return ;
}
[root@localhost process]# gcc main.c
[root@localhost process]# ./a.out | grep "test"
the test-env is:this is a test env
after unsetenvthe test-env is:(null)
[root@localhost process]#
GETPID() Linux Programmer’s Manual GETPID()
NAME
getpid, getppid - get process identification
SYNOPSIS
#include <sys/types.h>
#include <unistd.h> pid_t getpid(void);
pid_t getppid(void); DESCRIPTION
getpid() returns the process ID of the current process. (This is often used by
routines that generate unique temporary filenames.) getppid() returns the process ID of the parent of the current process.
#include <stdio.h>
#include <unistd.h> int main(void)
{
pid_t pid;
pid_t ppid; printf("pid=%d, ppid=%d\n", getpid(),getppid());
return ;
}
[root@localhost fork]# ./a.out
pid=, ppid=
[root@localhost fork]# ps aux | grep "bash"
root 0.0 0.3 pts/ Ss : : bash
可以发现父进程的 进程ID为 714,我们通过 ps 命令查看,可以知道 bash 的PID 为 714 ,因为 ./a.out 是由
EXEC() Linux Programmer’s Manual EXEC() NAME
execl, execlp, execle, execv, execvp - execute a file SYNOPSIS
#include <unistd.h> extern char **environ; int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg,
..., char * const envp[]);
int execv(const char *path, char *const argv[]); //参数以数组的形式传递
int execvp(const char *file, char *const argv[]); //参数以数组的形式传递
exec函数族的函数,将指定的可执行程序加载到调用exec函数的进程空间执行。如果exec函数执行成功,
#include <stdio.h>
#include <unistd.h> int main(int argc,char* argv[])
{
pid_t pid; printf("in program %s, pid=%d\n",argv[],getpid()); execl("test","from caller",NULL); //exec从默认路径搜索 test 可执行文件,我系统中默认路径没有 test 可知文件,执行会失败
perror("execl"); return ;
}
#include <stdio.h>
#include <stdlib.h> int main(int argc,char* argv[])
{
pid_t pid; printf("argv[1]=%s, pid=%d\n",argv[],getpid()); return ;
}
执行结果如下:
[root@localhost fork]# vim main.c
[root@localhost fork]# vim test.c
[root@localhost fork]# gcc main.c
[root@localhost fork]# gcc -o test test.c
[root@localhost fork]# ./a.out
in program ./a.out, pid=
execl: Bad address //execl( ) 函数执行失败返回
#include <stdio.h>
#include <unistd.h> int main(int argc,char* argv[])
{
pid_t pid; printf("in program: %s, pid=%d\n",argv[],getpid()); execl("./test","test","aa",NULL); //指定test可执行文件在当前目录下
perror("execl"); printf("if execl execute successfull this statement never reach");
return ;
}
#include <stdio.h>
#include <stdlib.h> int main(int argc,char* argv[])
{
pid_t pid; printf("in program: %s, pid=%d\n",argv[],getpid()); return ;
}
[root@localhost fork]# gcc main.c
[root@localhost fork]# gcc -o test test.c
[root@localhost fork]# ./a.out
in program: ./a.out, pid= //执行a.out ,并加载启动 test 可知文件
in program: test, pid= //test 可执行文件加启动成功
[root@localhost fork]#
FORK() Linux Programmer’s Manual FORK()
NAME
fork - create a child process SYNOPSIS
#include <sys/types.h>
#include <unistd.h> pid_t fork(void);
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h> int main(int argc,char* argv[])
{
pid_t pid; //创建新进程
pid=fork();
if( ==pid ) // 如果pid==0 则表示在子进程的进程空间
{
//下面的代码在子进程的进程空间执行
printf("Now you a in child process\n");
printf("my pid= %d\n",getpid());
printf("the process that create me is :%d\n",getppid());
exit(); //在子进程中退出
} //下面的代码在父进程的空间执行
printf("my pid= %d\n",getpid());
printf("the process that create me is :%d\n",getppid()); return ;
}
[root@localhost fork]# vim fork.c
[root@localhost fork]# gcc fork.c
[root@localhost fork]# ./a.out //第一次执行
Now you a in child process //子进程空间
my pid= //父进程空间
my pid= //子进程空间
the process that create me is : //子进程空间
the process that create me is : //父进程空间
[root@localhost fork]# ./a.out //第二次执行
Now you a in child process //子进程空间
my pid= //子进程空间
the process that create me is : //子进程空间
my pid= //父进程空间
the process that create me is : //父进程空间
[root@localhost fork]#
WAIT() Linux Programmer’s Manual WAIT()
NAME
wait, waitpid - wait for process to change state //等待某一个进程的状态的改变
SYNOPSIS
#include <sys/types.h>
#include <sys/wait.h> pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);
int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);
All of these system calls are used to wait for state changes in a child of the
calling process, and obtain information about the child whose state has changed.
A state change is considered to be: the child terminated; the child was stopped by
a signal; or the child was resumed by a signal. In the case of a terminated
child, performing a wait allows the system to release the resources associated
with the child; if a wait is not performed, then terminated the child remains in a
"zombie" state (see NOTES below).
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h> int main(int argc,char* argv[])
{
pid_t pid;
int status; //创建新进程
pid=fork();
if( ==pid )
{
printf("Now you a in child process ");
printf("my pid= %d\n",getpid());
printf("the process that create me is :%d\n\n",getppid());
exit();
}
//等待子进程的状态改变, 只有子进程的状态改变了wait才能返回,否则就阻塞父进程
wait(&status); printf("my pid= %d\n",getpid());
printf("the process that create me is :%d\n",getppid()); return ;
}
[root@localhost fork]# gcc fork.c
[root@localhost fork]# ./a.out //第一次执行
Now you a in child process my pid=
the process that create me is : my pid=
the process that create me is :
[root@localhost fork]# ./a.out //第二次执行
Now you a in child process my pid=
the process that create me is : my pid=
the process that create me is :
[root@localhost fork]#
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h> int main(int argc,char* argv[])
{
pid_t pid;
int status; //创建新进程
pid=fork();
if( ==pid )
{
sleep();
printf("Now you a in child process ");
printf("my pid= %d\n",getpid());
printf("the process that create me is :%d\n",getppid());
exit();
} //等待子进程的状态改变
//wait(&status);
waitpid(pid,&status,WNOHANG);//函数立即返回,并且通过输出参数status获取子进程的状态 printf("my pid= %d\n",getpid());
printf("the process that create me is :%d\n",getppid()); return ;
}
[root@localhost fork]# gcc fork.c
[root@localhost fork]# ./a.out
my pid= //父进程中waitpid 已经返回
the process that create me is : //父进程输出信息后已经结束
[root@localhost fork]# Now you a in child process my pid= //子进程开始输出信息,
the process that create me is : [root@localhost fork]#
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <string.h>
#include <fcntl.h> int main(int argc,char* argv[])
{
pid_t pid;
int status;
int fd;
char buf[];
int size;
int i;
int j; fd=open("./txt",O_RDWR | O_CREAT | O_TRUNC);
if(- == fd)
{
perror("open txt");
exit();
} //创建新进程
pid=fork();
if( ==pid )
{
for(i=;i<;i++)
{
j=;
size=sprintf(buf,"in child process pid=%d ppid=%d i=%d\n",getpid(), getppid(),i);
while(buf[j])
{
usleep();
write(fd,&buf[j++],);
}
}
exit();
} for(i=;i<;i++)
{
j=;
size=sprintf(buf,"in parent process pid=%d ppid=%d i=%d\n",getpid(), getppid(),i);
while(buf[j])
{
write(fd,&buf[j++],);
usleep();
}
}
//waitpid(pid,&status,WNOHANG);//函数立即返回,并且通过输出参数status获取子进程的状态 close(fd);
return ;
}
in ipnar ecnth i plrocde spsr opcieds=s2 7p8i4d3= 7p8p4i4d = 7p1p4i di==
8i4n3 pia=r0e
nitn cphriolcde spsr opcieds=s2 7p8i4d3= 7p8p4i4d = 7p1p4i di==
8i4n3 pia=r1e
nitn cphriolcde spsr opcieds=s2 7p8i4d3= 7p8p4i4d = 7p1p4i di==
8i4n3 pia=r2e
nitn cphriolcde spsr opcieds=s2 7p8i4d3= 7p8p4i4d = 7p1p4i di==
8i4n3 pia=r3e
nitn cphriolcde spsr opcieds=s2 7p8i4d3= 7p8p4i4d = 7p1p4i di==
8i4n3 pia=r4e
nitn cphriolcde spsr opcieds=s2 7p8i4d3= 7p8p4i4d = 7p1p4i di==
8i4n3 pia=r5e
nitn cphriolcde spsr opcieds=s2 7p8i4d3= 7p8p4i4d = 7p1p4i di==
8i4n3 pia=r6e
nitn cphriolcde spsr opcieds=s2 7p8i4d3= 7p8p4i4d = 7p1p4i di==
8i4n3 pia=r7e
nitn cphriolcde spsr opcieds=s2 7p8i4d3= 7p8p4i4d = 7p1p4i di==
8i4n3 pia=r8e
nitn cphriolcde spsr opcieds=s2 7p8i4d3= 7p8p4i4d = 7p1p4i di==
i=
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <string.h>
#include <fcntl.h> int main(int argc,char* argv[])
{
pid_t pid;
int status;
int fd;
char buf[];
int size;
int i;
int j; fd=open("./txt",O_RDWR | O_CREAT | O_TRUNC);
if(- == fd)
{
perror("open txt");
exit();
} //创建新进程
pid=fork();
if( ==pid )
{
for(i=;i<;i++)
{
j=;
size=sprintf(buf,"in child process pid=%d ppid=%d i=%d\n",getpid(), getppid(),i);
while(buf[j])
{
usleep();
write(fd,&buf[j++],);
}
}
exit();
} wait(&status); //等待子进程状态改变,新增加的代码
for(i=;i<;i++)
{
j=;
size=sprintf(buf,"in parent process pid=%d ppid=%d i=%d\n",getpid(), getppid(),i);
while(buf[j])
{
write(fd,&buf[j++],);
usleep();
}
}
//waitpid(pid,&status,WNOHANG);//函数立即返回,并且通过输出参数status获取子进程的状态 close(fd);
return ;
}
in child process pid= ppid= i=
in child process pid= ppid= i=
in child process pid= ppid= i=
in child process pid= ppid= i=
in child process pid= ppid= i=
in child process pid= ppid= i=
in child process pid= ppid= i=
in child process pid= ppid= i=
in child process pid= ppid= i=
in child process pid= ppid= i=
in parent process pid= ppid= i=
in parent process pid= ppid= i=
in parent process pid= ppid= i=
in parent process pid= ppid= i=
in parent process pid= ppid= i=
in parent process pid= ppid= i=
in parent process pid= ppid= i=
in parent process pid= ppid= i=
in parent process pid= ppid= i=
in parent process pid= ppid= i=
【linux草鞋应用编程系列】_2_环境变量和进程控制
本系列文章未完,待续。
如果您发现,文章有疏漏之处请不吝指教,包括错别字,标点符号等任何错误。
【linux草鞋应用编程系列】_2_ 环境变量和进程控制的更多相关文章
- 【linux草鞋应用编程系列】_3_ 进程间通信
一.进程间通信 linux下面提供了多种进程间通信的方法, 管道.信号.信号量.消息队列.共享内存.套接字等.下面我们分别 介绍管道.信号量.消息队列.共享内存. 信号和套 ...
- 【linux草鞋应用编程系列】_5_ Linux网络编程
一.网络通信简介 第一部分内容,暂时没法描述,内容实在太多,待后续专门的系列文章. 二.linux网络通信 在linux中继承了Unix下“一切皆文件”的思想, 在linux中要实现网 ...
- 【linux草鞋应用编程系列】_4_ 应用程序多线程
一.应用程序多线程 当一个计算机上具有多个CPU核心的时候,每个CPU核心都可以执行代码,此时如果使用单线程,那么这个线程只能在一个 CPU上运行,那么其他的CPU核心就处于空闲状态,浪费了系 ...
- 【linux草鞋应用编程系列】_1_ 开篇_系统调用IO接口与标准IO接口
最近学习linux系统下的应用编程,参考书籍是那本称为神书的<Unix环境高级编程>,个人感觉神书不是写给草鞋看的,而是 写给大神看的,如果没有一定的基础那么看这本书可能会感到有些头重脚轻 ...
- 【linux草鞋应用编程系列】_6_ 重定向和VT100编程
一.文件重定向 我们知道在linux shell 编程的时候,可以使用文件重定向功能,如下所示: [root@localhost pipe]# echo "hello world&q ...
- linux下查看和添加PATH环境变量
linux下查看和添加PATH环境变量 $PATH:决定了shell将到哪些目录中寻找命令或程序,PATH的值是一系列目录,当您运行一个程序时,Linux在这些目录下进行搜寻编译链接. 编辑你的 PA ...
- Linux操作系统下三种配置环境变量的方法
现在使用linux的朋友越来越多了,在linux下做开发首先就是需要配置环境变量,下面以配置java环境变量为例介绍三种配置环境变量的方法. 1.修改/etc/profile文件 如果你的计算机仅仅作 ...
- Linux 下三种方式设置环境变量
1.在Windows 系统下,很多软件安装都需要配置环境变量,比如 安装 jdk ,如果不配置环境变量,在非软件安装的目录下运行javac 命令,将会报告找不到文件,类似的错误. 2.那么什么是环境变 ...
- Linux操作系统下三种配置环境变量的方法——转载
来源:赛迪网 作者:millio 现在使用linux的朋友越来越多了,在linux下做开发首先就是需要配置环境变量,下面以配置java环境变量为例介绍三种配置环境变量的方法. 1.修改/e ...
随机推荐
- ASP.NET MVC 控制器激活(一)
ASP.NET MVC 控制器激活(一) 前言 在路由的篇章中讲解了路由的作用,讲着讲着就到了控制器部分了,从本篇开始来讲解MVC中的控制器,控制器是怎么来的?MVC框架对它做了什么?以及前面有的篇幅 ...
- 老司机学Xamarin系列总目录
Xamarin开发环境及开发框架初探 Xamarin Forms开发框架二探 (Prism vs MvvmCross) Xamarin Forms开发框架之MvvmCross插件精选 Xamarin开 ...
- Qt And MFC UI Layout
界面布局 起初,计算机的交互是通过输入的代码进行的, 慢慢的有了图形之后, 就开始了图形界面的交互. 目前来说还有语音交互, 视频交互等多媒体的交互. 不管哪一种交互, 最终在计算机的角度都是信号的输 ...
- 操作数据库mysql
显示表结构 desc 表 显示数据库信息 show create database 数据库名 show create table 表名
- 探讨Js的事件的冒泡阶段
近来看到了一个新的知识点叫Js的事件冒泡,因此决定自己来研究一番. 大家应该都知道,Js中的事件处理分为三个阶段,1:事件的捕获阶段,2:处于目标阶段,3:事件的冒泡阶段.那么什么是事件的捕获和冒泡呢 ...
- ThinkPHP3.2设置404跳转页面
在ThinkPHP3.2版本中当我们访问不存在的页面时会出现非常不友好错误提示页面,类如下图: 解决办法: 1.在ThinkPHP3.2详细的介绍了该框架下的ThinkPHP惯例配置文件convent ...
- 扩:new and override
昨天有个网友问我继承里面的new和override关键词有啥区别,呃,我们来看个例子就知道了 new ==>隐藏父类同名方法 override==>覆盖 定义一个父类: public c ...
- 安装CentOS、Linux系统时,GPT分区不能引导的解决方法
安装系统:CentOS 5.9_64bit时,分区后, 提示如下错误. 解决方法: 1.按ctrl+alt+F2 进入命令行 2.先查看分区 sh #fdisk -l 以下假设分区是/dev/s ...
- SQL 截取字符串
以下代码演示的是除去字符串后四位 ,) 下面是SUBSTRING的解释 SUBSTRING ( expression ,start , length ) 第一个参数是字符串,第二个是起始位置,第三个是 ...
- Android okHttp网络请求之Retrofit+Okhttp+RxJava组合
前言: 通过上面的学习,我们不难发现单纯使用okHttp来作为网络库还是多多少少有那么一点点不太方便,而且还需自己来管理接口,对于接口的使用的是哪种请求方式也不能一目了然,出于这个目的接下来学习一下R ...