LInux|命令行参数|环境变量
- 命令行参数
- main的参数之argc,argv
- 几个小知识
- <font color=#0099ff size = 5 face="黑体">1.子进程默认能看到并访问父进程的数据
- <font color=#4b0082 size = 5 face="黑体">2.命令行创建的程序父进程都是bash
- 环境变量
- 怎么才能让我们的命令和系统的一样?
- 见见更多的环境变量
- 自定义环境变量
- 代码获取环境变量
- environ 全局变量
- main的第三个参数
- getenv() 获得单个的环境变量
- 内建命令
可能我们在最开始学c语言的时候会看到下面这种写法
命令行参数
int main(int argc char * argv)
{
//...
}
这种写法的参数什么意思了? main函数的参数其实是命令行参数
int main(int argc, char* argv[])
{
for (int i = 0; i < argc; i++)
{
printf("argv[%d]->%s\n", i, argv[i]);
}
return 0;
}
我们在命令行里输入的都是字符串
main的参数之argc,argv
argv是一个数组,里面的元素是char* 的指针,这里char*的指针用来指向字符串。 argc是argv数组的元素个数
注意 argv 最后一个元素为空
我们可以根据 argc 和 argv 实现 同一个程序实现不同的选项
#include<string.h>
#include<stdio.h>
int main(int argc, char* argv[])
{
if (argc != 2)
{
printf("useage:[-a -b ]\n");
return 1;
}
if (strcmp(argv[1], "-a") == 0)
{
printf("this is function1\n");
}
else if (strcmp(argv[1], "-b") == 0)
{
printf("this is function2\n");
}
else
{
printf("there is no this function\n");
}
return 0;
}
几个小知识
1.子进程默认能看到并访问父进程的数据
#include<string.h>
#include<unistd.h>
#include<stdio.h>
#include<sys/types.h>
int g_bal = 100;
int main( int argc, char *argv[])
{
printf("I am father process,pid:%d,getppid:%d ,g_bal:%d\n",getpid(),getppid(),g_bal);
pid_t id = fork();
sleep(5);
if(id == 0 )
{
// child
while(1)
{
printf("I am child process,pid:%d,g_bal:%d\n",getpid(),g_bal);
sleep(5);
}
}
else
{
while(1)
{
printf("I am father process,pid:%d,g_bal:%d\n",getpid(),g_bal);
sleep(5);
}
}
return 0;
}
这个代码的现象就是 子进程也能打印出100
2.命令行创建的程序父进程都是bash
我们多次 启动这个程序 可以看到 pid 不同但是ppid 却是相同的(可能有机器不一样 我的bash进程的pid是25663)bash其实就是命令行解释器,bash读了字符串之后交给了子进程。
环境变量
我们知道 ls 也是程序 为什么我写的程序要./才能运行 而ls这种不需要呢?当然我们也可以带绝对路径运行ls /usr/bin/ls Linux环境下存在一些全局的设置,告诉命令行解释器去哪些路径下找可执行程序 系统中很多配置,在我们登陆Linux的时候已经被加载到bash(内存)中了。 PATH环境变量,想打印它的内容必须上$
怎么才能让我们的命令和系统的一样?
方案一 我们可以把可执行文件拷贝到usr/bin目录下,这相当于把我们的程序安装到Linux系统里 我们不建议这么干 因为会污染指令集
方案二 我们可以修改PATH的值PATH=/home/lj/lesson13这相当于把PATH原来的值覆盖了,导致系统找不到ls等系统指令了但是不用担心,我们重新登陆Linux又恢复原来的样子了因为 bash 是从一个文件中读取的环境变量,我们这里修改的只是内存级的 那我们怎么才能保存原先的值呢? PATH=$PATH:/home/lj/lesson13 但是这样还是没修改文件,我们才能让他永久有效呢 修改家目录的.bash_profile文件
见见更多的环境变量
- HOME 记录该用户的家目录
- PWD 记录该用户所在的路径
- SHELL 查看所用的哪种解释器
- HISTSIZE 记录最新的1000条历史指令
如果我们想看更多的环境变量可以使用 env命令
我们如果想自己定义环境变量也是可以的
自定义环境变量
export 环境变量名 = 值
如果不加exportecho这样能查到但是没有导入在.bash_profile文件里则称为本地变量
代码获取环境变量
environ 全局变量
#include<string.h>
#include<unistd.h>
#include<stdio.h>
#include<sys/types.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
extern char ** environ;
int i = 0;
for(; environ[i]; i++){
printf("%s\n", environ[i]);
}
return 0;
}
这个运行出来和我们用env命令一样的 这表明bash的子进程也能读取到环境变量,则并不奇怪因为最开始环境变量在文件里,bash读到该进程中,子进程本来就能访问父进程里面的数据
为什么是char**?
因为每个数组元素是char * 要想指向这张环境变量表只能是char**
main的第三个参数
main函数默认会生成两张表一张是环境变量表另一张是命令行参数表
#include <stdio.h>
int main(int argc, char *argv[], char *env[])
{
int i = 0;
for(; env[i]; i++){
printf("%s\n", env[i]);
}
return 0;
}
getenv() 获得单个的环境变量
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("%s\n", getenv("PATH"));
return 0;
}
内建命令
LInux中百分之八十的命令都是bash创建子进程执行的,剩下的命令相当于是bash内部的函数这称为内建命令 我们子进程新产生的数据 父进程是看不到的
我们的echo,export都是内建命令 正因为export没有创建bash的子进程才能将数据导给bash