【Linux详解】——环境变量

📖 前言:本期将介绍Linux下的环境变量


🕒 1. 基本概念

首先问个问题:为什么运行自己写的程序需要路径,而系统的指令不用路径?
答:是因为系统能找到他的位置。系统中是存在相关的环境变量,保存了程序的搜索路径的!系统中搜索可执行程序的环境变量叫做PATH!
解决方法:把你的程序拷贝到/usr/bin/(不推荐,推荐方法见下面)

  • 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数
  • 如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。
  • 环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性

🕘 1.1 常见环境变量

  • PATH : 指定命令的搜索路径
  • HOME : 指定用户的主工作目录 ( 即用户登陆到 Linux 系统中时 , 默认的目录 )
  • SHELL : 当前 Shell, 它的值通常是 /bin/bash 。

🕘 1.2 查看环境变量方法

echo $NAME //NAME:你的环境变量名称

[hins@VM-12-13-centos test_process_2]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/hins/.local/bin:/home/hins/bin

这样就可以显示PATH里面的内容,而不是单纯去把PATH当字符串打印出来

导入环境变量:export PATH=$PATH:/home/hins/testLinux/test_process_2

注:其中的 $PATH 代表之前PATH中内容,: 之后的为新添加的内容;注意不要直接 “export PATH=/home/hins/testLinux/test_process_2”,这样会把之前的PATH覆盖掉,使得Linux中的各种指令必须指定路径使用;同时,PATH中不能用空格,因为Linux中以空格为分隔符。

这样就可以正常使用了

Windows下查看环境变量:设置->关于->高级系统设置->环境变量
在这里插入图片描述

🕘 1.3 其他指令:

[hins@VM-12-13-centos test_process_2]$ echo $HOSTNAME	# 查看当前云服务器名
VM-12-13-centos
[hins@VM-12-13-centos test_process_2]$ echo $PWD		# 查看当前路径
/home/hins/testLinux/test_process_2
[hins@VM-12-13-centos test_process_2]$ echo $LOGNAME	# 查看当前用户名
hins
[hins@VM-12-13-centos test_process_2]$ echo $HOME		# 查看当前用户的家目录
/home/hins
[hins@VM-12-13-centos test_process_2]$ echo $HISTSIZE	# 查看历史命令总容量
3000
[hins@VM-12-13-centos test_process_2]$ history   		# 查看历史输入过的指令
    1  2022-10-23 09:57:05 whoami
    2  2022-10-23 09:57:13 which whoami
    3  2022-10-23 09:57:50 sudo whoami
    4  2022-10-23 10:05:51 pwd
......

小结:

  1. echo: 显示某个环境变量值
  2. export: 设置一个新的环境变量
  3. env: 显示所有环境变量
XDG_SESSION_ID=122878
HOSTNAME=VM-12-13-centos
TERM=xterm
SHELL=/bin/bash
HISTSIZE=3000
SSH_CLIENT=120.231.141.160 28506 22
OLDPWD=/home/hins/testLinux
SSH_TTY=/dev/pts/0
USER=hins
LD_LIBRARY_PATH=:/home/hins/.VimForCpp/vim/bundle/YCM.so/el7.x86_64
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:
MAIL=/var/spool/mail/hins
PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/hins/.local/bin:/home/hins/bin
PWD=/home/hins/testLinux/test_process_2
LANG=en_US.utf8
SHLVL=1
HOME=/home/hins
LOGNAME=hins
SSH_CONNECTION=120.231.141.160 28506 10.0.12.13 22
LESSOPEN=||/usr/bin/lesspipe.sh %s
PROMPT_COMMAND=history -a; history -a; printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"
XDG_RUNTIME_DIR=/run/user/1001
HISTTIMEFORMAT=%F %T 
_=/usr/bin/env
  1. unset: 清除环境变量
  2. set:显示本地定义的shell变量和环境变量

🕘 1.4 环境变量的来源

在这里插入图片描述

# .bash_profile   
                                                                                
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
	. ~/.bashrc
fi

# User specific environment and startup programs
 
PATH=$PATH:$HOME/.local/bin:$HOME/bin

export PATH
# .bashrc                                                                                         

# Source global definitions
if [ -f /etc/bashrc ]; then
   . /etc/bashrc
fi

# Uncomment the following line if you don't like systemctl's auto-paging feature:
# export SYSTEMD_PAGER=

# User specific aliases and functions
alias vim='/home/hins/.VimForCpp/nvim'
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/.VimForCpp/vim/bundle/YCM.so/el7.x86_64

在我们登录 shell 时,操作系统会让我们当前的 shell 进程执行 .bash_profile 中的内容,而 .bash_profile 又会调用执行 .bashrc,它们会将对应的环境变量导入到 shell 进程的上下文环境中。所以,如果我们上面不小心将 $PATH 覆盖掉了也不用担心,重新登录 shell 就好了。

至此,环境变量的定义如下:

环境变量是操作系统为了满足不同的应用场景,预先在系统内设置的一大批全局变量,这些变量往往具有特殊功能,且能够一直被 bash 以及 bash 的子进程访问。

注:环境变量具有全局属性的根本原因是环境变量会被子进程继承

🕒 2. 环境变量的操作

🕘 2.1 设置环境变量

Linux命令行其实是可以定义变量的,但是以这种方式定义出来的变量是本地变量,即只在 bash 进程中有效;而不是环境变量,因为环境变量具有全局属性:
我们可以使用 export 直接定义环境变量,也可以使用它将已存在的本地变量导为环境变量:

🕘 2.2 通过getenv获取环境变量

有了 getenv 函数后,我们就可以自己编写系统中的某些指令了,比如 pwd:

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

#define MYPWD "PWD"

int main()
{
    char* env = getenv(MYPWD);
    printf("%s\n", env);	// 输出路径
    return 0;
}

🕘 2.3 通过putenv获取环境变量

后面讲解

🕘 2.4 环境变量的意义

上面提到,环境变量是操作系统为了满足不同的应用场景,预先在系统内设置的一大批全局变量;其中 PATH 是为了满足我们指令路径搜索的需求,而除了指令需求之外还有许多其他需求,其中非常重要的一个就是 身份认证。

我们以一个例子说明:

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

#define USER "USER"

int main()
{
    char* who = getenv(USER);
    if(strcmp(who, "root") == 0)
    {
        printf("Operation success!\n");
    }
    else 
    {
        printf("Permission denied!\n");
    }
    return 0;
}
[hins@VM-12-13-centos test_env]$ echo $USER
hins
[hins@VM-12-13-centos test_env]$ ./mycmd
Permission denied!	
[hins@VM-12-13-centos test_env]$ su -
Password: 
Last login: Sat Oct 29 10:09:53 CST 2022 from 120.231.141.27 on pts/0
Last failed login: Tue Nov 15 14:49:41 CST 2022 on pts/0
There were 80330 failed login attempts since the last successful login.
[root@VM-12-13-centos ~]# cd /home/hins/testLinux/test_env
[root@VM-12-13-centos test_env]# echo $USER
root
[root@VM-12-13-centos test_env]# ./mycmd
Operation success!
[root@VM-12-13-centos test_env]# 

注:这里要使用 su -,而不能使用 su,因为 su - 会重新登录 shell,此时 shell 会重新加载环境变量,让 $USER 从 hins 变为 root;而 su 只是把用户身份切换为 root。

我们可以在程序内部通过 getenv 函数来获取当前的Linux用户,然后判断其是否具备某种权限,再执行对应操作;

另外,我们还可以通过 stat 来获取一个文件的其他属性,比如读写执行等,然后根据这些属性判断一个用户是否能对该文件进行操作:

🕒 3. 命令行参数

我们上面提到,程序可以通过 getenv 函数来获取环境变量,其实除了 getenv 函数,程序还可以通过命令行参数传递来获取环境变量。

在C语言中,main 函数其实是有参数的,且这些参数通过命令行传递:

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

其中 argv 是一个指针数组,数组里面的每一个元素都指向一个字符串,argc 用来指定数组元素的个数;它们配合使用可以实现类似于 ls -a -l -d 选项的功能。就是同一个程序,通过传递不同的参数(选项),让同一个程序有不同的执行逻辑,产生不同的结果。

而指针数组 env 就是用于接受父进程传递过来环境变量的参数,我们可以通过在 main 函数中打印 env 中的内容来验证它:

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

int main(int argc, char* argv[], char* env[])
{
    int i = 0;
    for(i=0; env[i]; i++)
    {
        printf("env[%d]:%s\n", i, env[i]);
    }
    return 0;
}
[hins@VM-12-13-centos test_env]$ ./mycmd
env[0]:XDG_SESSION_ID=123580
env[1]:HOSTNAME=VM-12-13-centos
env[2]:TERM=xterm
env[3]:SHELL=/bin/bash
env[4]:HISTSIZE=3000
env[5]:SSH_CLIENT=120.231.141.160 28439 22
env[6]:OLDPWD=/home/hins
env[7]:SSH_TTY=/dev/pts/0
env[8]:USER=hins
env[9]:LD_LIBRARY_PATH=:/home/hins/.VimForCpp/vim/bundle/YCM.so/el7.x86_64
env[10]:LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:
env[11]:MAIL=/var/spool/mail/hins
env[12]:PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/hins/.local/bin:/home/hins/bin
env[13]:PWD=/home/hins/testLinux/test_env
env[14]:LANG=en_US.utf8
env[15]:SHLVL=1
env[16]:HOME=/home/hins
env[17]:LOGNAME=hins
env[18]:SSH_CONNECTION=120.231.141.160 28439 10.0.12.13 22
env[19]:LESSOPEN=||/usr/bin/lesspipe.sh %s
env[20]:PROMPT_COMMAND=history -a; history -a; printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"
env[21]:XDG_RUNTIME_DIR=/run/user/1001
env[22]:HISTTIMEFORMAT=%F %T 
env[23]:_=./mycmd

程序也可以通过环境表 environ 来获取环境变量 – 环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串;每个进程都会收到一张环境表:
在这里插入图片描述

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

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

OK,以上就是本期知识点“环境变量”的知识啦~~ ,感谢友友们的阅读。后续还会继续更新,欢迎持续关注哟📌~
💫如果有错误❌,欢迎批评指正呀👀~让我们一起相互进步🚀
🎉如果觉得收获满满,可以点点赞👍支持一下哟~

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值