linux环境变量_linux环境变量配置 - CSDN
精华内容
参与话题
  • Linux下的环境变量

    千次阅读 2017-12-22 19:05:45
    一、环境变量Linux环境变量包括系统级和用户级,系统级的环境变量是每个登录到系统的用户都要读取的系统变量,而用户级的环境变量则是该用户使用系统时加载的环境变量。 所以管理环境变量的文件也分为系统级和...

    一、环境变量

    Linux中环境变量包括系统级和用户级,系统级的环境变量是每个登录到系统的用户都要读取的系统变量,而用户级的环境变量则是该用户使用系统时加载的环境变量。
    所以管理环境变量的文件也分为系统级和用户级的.

    1.系统级:

    (1)/etc/environment: 是系统在登录时读取的第一个文件,用于为所有进程设置环境变量。系统使用此文件时并不是执行此文件中的命令,而是根据KEY=VALUE模式的代码,对KEY赋值以VALUE,因此文件中如果要定义PATH环境变量,只需加入一行形如PATH=$PATH:/xxx/bin的代码即可。
    (2)/etc/profile:是系统登录时执行的第二个文件,可以用于设定针对全系统所有用户的环境变量。该文件一般是调用/etc/bash.bashrc文件。
    /etc/bash.bashrc:系统级的bashrc文件,为每一个运行bash shell的用户执行此文件。此文件会在用户每次打开shell时执行一次。

    注意: /etc/environment是设置整个系统的环境,而/etc/profile是设置所有用户的环境,前者与登录用户无关,后者与登录用户有关。 这两个文件修改后一般都要重启系统才能生效。

    2.用户级(这些文件处于家目录下)

    1)~/.profile: 是对应当前登录用户的profile文件,用于定制当前用户的个人工作环境。
    每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时,该文件仅仅执行一次!默认情况下,他设置一些环境变量,执行用户的.bashrc文件。这里是推荐放置个人设置的地方
    (2)~/.bashrc: 是对应当前登录用户的bash初始化文件,当用户每次打开shell时,系统都会执行此文件一次。平时设置这个文件就可以了。

    那么根据以上描述,这几个文件的执行先后顺序应当是:
    /etc/enviroment –>/etc/profile –>~/.profile –>/etc/bash.bashrc–> ~/.bashrc

    二、配置环境变量

    1、在linux下设定环境变量时,如果只是临时用一下,可以直接在shell下用set或export命令设定环境变量。只能在当前shell脚本下可用.,切换到另一个终端就会失效。

    #终端输入:
    export PYTHONPATH=/home/yanting/learning/ssd-caffe/python  #PYTHONPATH设置为该路径
    #终端查看一个特定环境变量包含的内容,比如PYTHONPATH
    echo $PYTHONPATH

    2、如果希望此环境变量每次开机或打开shell时自动设定而无须每次都手动设定,那么需要将export命令写入以上的系统文件中。例如:
    (1)打开当前用户环境变量:
    终端输入:sudo gedit ~/.bashrc,输入用户密码,则会打开.bashrc文件,
    在其末尾添加:

    export PYTHONPATH=/home/yanting/learning/caffe/python:$PYTHONPATH  
    # path采用:来分隔,冒号左右不需要空格.
    # :$PYTHONPATH在后面新添加的path优先搜索,$PYTHONPATH:在前面说明新添加的path后面搜索,不加代表新路径设置为PYTHONPATH路径。

    其中/home/yanting/learning/caffe/python为自己需要设置的环境变量路径。

    在终端执行:source ~/.bashrc ,使其立即生效,或者重启电脑即可。

    (2)在终端使用 sudo gedit /etc/profile 打开环境变量的文件,然后将自己的环境变量加入到文件之后,用export 执行。
    在终端里面使用source /etc/profile 来更新环境变量

    3、采用export添加新的路径到环境变量PATH中。

    #比如添加搜索路径/home/cc/path1和/home/cc/path2 路径到PATH中,采用:来分隔,冒号左右不需要空格
    
    export PATH=$PATH:/home/cc/path1:/home/cc/path2
    #若需要将路径放在优先搜索位置,将$PATH放在后面
    
    export PATH=/home/cc/path1:/home/cc/pck:$PATH
    展开全文
  • 【Linux】完全解读Linux环境变量

    千次阅读 2016-06-27 18:17:15
    一、概述  环境变量:bash shell用一个称作“环境变量(environment variables)”的特性来存储有关shell会话和工作环境的信息,它允许你在内存中存储数据,... shell中的环境变量有全局环境变量和局部环境变量

    一、概述

            环境变量:bash shell用一个称作“环境变量(environment variables)”的特性来存储有关shell会话和工作环境的信息,它允许你在内存中存储数据,以便运行在shell上的程序和脚本访问,这些数据可以用来识别用户、账户、系统、shell特性以及任何其他你需要存储的数据。

            shell中的环境变量有全局环境变量和局部环境变量,通过KV(variable=value)的形式声明一个局部变量,export这个局部变量,则升级成为全局环境变量。既然shell分开来用,显然两者有区别,下面分开来讨论。

    1. 全局环境变量

            特性:声明一个全局环境变量,在当前shell进程以及子shell进程中可用,父shell进程中不可用,这里的“可用”可以理解成父shell进程全局环境变量的一个copy,而不是继承父类的全局环境变量两者共用一份,因此子shell进程中对父shell进程的全局环境变量进行增、删、该、查均无影响。

            证明一:1)全局变量在当前shell可用、子shell可用,但是父shell进程不可用;2)子shell copy了父shell进程的全局环境变量的副本,因此子shell对变量的操作对父类透明

    [html] view plain copy
     print?
    1. #!/bin/bash  
    2. #父shell进程  
    3. #       1. 声明一个全局环境变量  
    4. #       2. fork一个子shell进程  
    5. #               在子shell进程中可以访问父类定义的全局变量  
    6. #               在子shell中修改或删除(unset)父类定义的全局环境变量,对父进程没有影响  
    7. #               在子shell中增加一个全局环境变量,父类中是访问不到的  
    8. #       3. 父shell进程中访问被子shell进程修改或删除的全局环境变量,该变量值未改变  
    9. #       4. 父shell进程访问子类增加的子类全局环境变量:结果是访问不到  
    10. export testing="zhangsan"  
    11. echo "father定义了一个全局变量,初始值为:testing=zhangsan"  
    12. sh son.sh  
    13. echo "father访问被子类修改的全局变量:$testing"  
    14. echo "father访问子类增加的全局变量:$sonTest"  
    [html] view plain copy
     print?
    1. #!/bin/bash  
    2. #子shell进程  
    3.   
    4. echo "son访问父类shell进程中定义的全局变量:$testing"  
    5. testing="son zhangsan"  
    6. echo "son修改了父类的全局变量:testing=$testing"  
    7. export sonTest="son lizi"  
    8. echo "son增加了子类全局变量:$sonTest"  
    [html] view plain copy
     print?
    1. [work@localhost global]$ sh father.sh   
    2. father定义了一个全局变量,初始值为:testing=zhangsan  
    3. son访问父类shell进程中定义的全局变量:zhangsan  
    4. son修改了父类的全局变量:testing=son zhangsan  
    5. son增加了子类全局变量:son lizi  
    6. father访问被子类修改的全局变量:zhangsan  
    7. father访问子类增加的全局变量:  

            证明二:登录shell fork一个子shell进程,该子shell进程export一个全局环境变量,执行完成后在登录shell中没有该变量

    [html] view plain copy
     print?
    1. #!/bin/bash  
    2. #登录shell fork一个子shell进程  
    3. #       子shell进程声明一个全局环境变量  
    4. #       子shell执行完成之后,退出到登录shell  
    5. #       登录shell访问不到该变量  
    6.   
    7. export userName="zhangsan"  
            执行该脚本,执行完成后访问变量,没有值。
    [html] view plain copy
     print?
    1. [work@localhost global]$ sh var.sh   
    2. [work@localhost global]$ echo $userName  
    3.   
    4. [work@localhost global]$   

    2. 局部环境变量

            特性:当前shell进程可用,父、子shell进程不可用

            证明:父进程定义局部变量,子进程访问不到;子进程定义局部变量,父进程访问不到

    [html] view plain copy
     print?
    1. #!/bin/bash  
    2.   
    3. fatherVar="father var"  
    4. echo "father定义的局部变量:$fatherVar"  
    5. sh son.sh  
    6. echo "son定义的局部变量:$sonVar"  
    [html] view plain copy
     print?
    1. #!/bin/bash  
    2.   
    3. echo "son访问fanther定义的局部变量:$fatherVar"  
    4. sonVar="son var"  
    5. echo "son定义的局部变量:$sonVar"  
    [html] view plain copy
     print?
    1. [work@localhost local]$ sh father.sh   
    2. father定义的局部变量:father var  
    3. son访问fanther定义的局部变量:  
    4. son定义的局部变量:son var  
    5. son定义的局部变量:  

    3. 总结

            1. 全局环境变量:当前shell进程及子进程可用,父shell进程不可用,子进程对变量的修改对当前shell来说透明无影响;

            2. 局部环境变量:当前shell进程可用,父进程、子进程均不可用;

            3. 环境变量存在内存当中,断电后消失,如果想要在下一次系统加电后还可以访问:

                    a. 如果这个变量是系统级别的(所有用户共享),则可以在/etc/profile中export;

                    b. 如果这个变量只对当前用户有效,则可以在~/.bash_profile(或者~./bash_login,或者~./profile,或者~./bashrc,或者/etc/bashrc)中export;

            补充:本节讨论主要是fork进程方式,不包括source和exec,三种方式的差异在后面进行讨论;


    二、登陆shell

            环境变量存放在内存当中,断电后消失。但是你会发现类似USER、PATH、LOGNAME、HOSTNAME这些环境变量,只要系统一启动就存在了。这是为什么?

            操作系统因该具备至少5个功能:内存管理、文件系统管理、进程管理、设备管理(硬件)和用户接口管理,这里的用户接口不能理解成init 5启动界面功能或类似windows的界面,而是用户和系统内核交互的接口,即内核提供给外界的一组访问接口,所以在系统启动的时候,启动shell就是为此而生,他向用户提供了一组和Linux kernel交互的接口。

            登陆shell随着用户的登陆而启动,根据表现可以将其理解成后续交互shell、非交互shell的顶级父shell环境,因此在登陆shell中声明的全局环境变量,后续的所有shell都可以访问到,毫无疑问,局部变量例外。

            系统启动以后的第一个进程是init,他会进行系统初始化并打开命令行终端,建立命令行所必须的stdin, stdout, stderr,这时候用户才能进行系统登录。当你输入用户名的时候,/bin/login程序会验证你输入的用户名是否在/etc/passwd中,如果存在,则继续在/etc/shadow中验证你输入的密码。一旦验证通过,/bin/login程序就会提取/etc/passwd中和用户相关的HOME, LOGNAME, SHELL, USER等变量来定义一个工作环境,此时/etc/passwd的最后一项将会被执行,也就是用户默认的shell,这个shell也就是本节介绍的登陆shell的来源。

            登陆shell首先会到/etc/profile中读取命令并执行,读取执行该文件,主要做了两件事:

            1. 定义并 声明全局的环境变量,export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL,所有的shell进程都可以访问到这些变量;

            2. 到/etc/profile.d目录中执行该目录下的应用启动文件,这个目录集中存放了一些应用的启动文件,这些应用随着系统启动而启动,譬如vim、less等,类似于windows中的启动项中定义的一些开机自运行的软件;

            /etc/profile.d目录下的内容和/etc/profile的内容如下:


    [html] view plain copy
     print?
    1. # /etc/profile  
    2.   
    3. # System wide environment and startup programs, for login setup  
    4. # Functions and aliases go in /etc/bashrc  
    5.   
    6. # It's NOT a good idea to change this file unless you know what you  
    7. # are doing. It's much better to create a custom.sh shell script in  
    8. # /etc/profile.d/ to make custom changes to your environment, as this  
    9. # will prevent the need for merging in future updates.  
    10.   
    11. pathmunge () {  
    12.     case ":${PATH}:" in  
    13.         *:"$1":*)  
    14.             ;;  
    15.         *)  
    16.             if [ "$2" = "after" ] ; then  
    17.                 PATH=$PATH:$1  
    18.             else  
    19.                 PATH=$1:$PATH  
    20.             fi  
    21.     esac  
    22. }  
    23.   
    24.   
    25. if [ -x /usr/bin/id ]; then  
    26.     if [ -z "$EUID" ]; then  
    27.         # ksh workaround  
    28.         EUID=`id -u`  
    29.         UID=`id -ru`  
    30.     fi  
    31.     USER="`id -un`"  
    32.     LOGNAME=$USER  
    33.     MAIL="/var/spool/mail/$USER"  
    34. fi  
    35.   
    36. # Path manipulation  
    37. if [ "$EUID" = "0" ]; then  
    38.     pathmunge /sbin  
    39.     pathmunge /usr/sbin  
    40.     pathmunge /usr/local/sbin  
    41. else  
    42.     pathmunge /usr/local/sbin after  
    43.     pathmunge /usr/sbin after  
    44.     pathmunge /sbin after  
    45. fi  
    46.   
    47. HOSTNAME=`/bin/hostname 2>/dev/null`  
    48. HISTSIZE=1000  
    49. if [ "$HISTCONTROL" = "ignorespace" ] ; then  
    50.     export HISTCONTROL=ignoreboth  
    51. else  
    52.     export HISTCONTROL=ignoredups  
    53. fi  
    54.   
    55. JAVA_HOME=/usr/java/jdk1.7.0_75  
    56. CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar  
    57. PATH=$PATH:$JAVA_HOME/bin  
    58. export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL  
    59.   
    60. # By default, we want umask to get set. This sets it for login shell  
    61. # Current threshold for system reserved uid/gids is 200  
    62. # You could check uidgid reservation validity in  
    63. # /usr/share/doc/setup-*/uidgid file  
    64. if [ $UID -gt 199 ] && [ "`id -gn`" = "`id -un`" ]; then  
    65.     umask 002  
    66. else  
    67.     umask 022  
    68. fi  
    69.   
    70. for i in /etc/profile.d/*.sh ; do  
    71.     if [ -r "$i" ]; then  
    72.         if [ "${-#*i}" != "$-" ]; then  
    73.             . "$i"  
    74.         else  
    75.             . "$i" >/dev/null 2>&1  
    76.         fi  
    77.     fi  
    78. done  
    79.   
    80. unset i  
    81. unset -f pathmunge  

            至此,所有用户登录系统到这一步的时候,他们之间的pringenv是没有差别的,但实际上无论是哪一个用户登录系统,printenv打印的全局环境变量都是不一样的,因为登陆shell在加载执行/etc/profile之后还有一系列的个性化操作,这些操作的内容记录在各个用户目录。

    1. 不同用户的登陆shell全局环境变量

            不同的用户登录系统,printenv的结果是不一样的,也就是说不同的用户有不同的shell进程环境,登录shell是顶级环境。先来验证一下,再来进行说明。

            验证一:不同用户登录,其全局环境变量不一样,此处选择root和work用户,测试全局环境变量PATH

                    步骤一:work账户登录,echo $PATH > /home/work/var.path

                    步骤二:切换用户以及环境到root,su - root,echo $PATH >> /home/work/var.path

                    步骤三:cat /home/work/var.path,比较两行值,执行结果如下所示

    [html] view plain copy
     print?
    1. [work@localhost ~]$ echo $PATH > /home/work/xx.path  
    2. [work@localhost ~]$ su - root   
    3. Password:   
    4. [root@localhost ~]# echo $PATH >> /home/work/xx.path  
    5. [root@localhost ~]# cat /home/work/xx.path   
    6. /usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/java/jdk1.7.0_75/bin:/home/work/bin  
    7. /usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/java/jdk1.7.0_75/bin:/root/bin  

    2. 登录shell的个性化详解

            登录shell在启动shell之上又加入了个性化,不同用户获得的登录环境是不一样的。除root用户之外,Linux上其他用户的主目录是/home/xxx,要进行个性化,必然在此做文章。

            登录shell的入口,~/.bash_profile文件。

    a. .bash_profile文件

            当你输入用户名和密码登录系统的时候,启动shell进程会fork一个登录shell进程,这个登录shell进程会到当前登录用户的主目录下顺序读取(如果存在)文件~/.bash_profile、~/.bash_login、~/.profile 中的指令并执行,需要注意的是这三个文件不一定都存在(我的系统centos 2.6.32中就只存在.bash_profile),如果存在多个,则按照列出顺序进行读取指令并执行。

            读取到.bash_profile主要做了两件事情,一件是source(最后一节会有source的详解)~/.bashrc这个文件,另一件是重新export PATH,详细内容如下。

    [html] view plain copy
     print?
    1. # .bash_profile  
    2.   
    3. # Get the aliases and functions  
    4. if [ -f ~/.bashrc ]; then  
    5.         . ~/.bashrc  
    6. fi  
    7.   
    8. # User specific environment and startup programs  
    9.   
    10. PATH=$PATH:$HOME/bin  
    11.   
    12. export PATH  

    b. .bashrc文件

            由此,可知不同用户的环境变量PATH不一致的原因。但是source ~/.bashrc这个文件又做了什么事情?

            .bashrc文件也做了两件事,一件是定义一些别名(定义别名,你可以在当前shell中任意使用,类似定义局部环境变量),另一件事是source了/etc/bashrc文件。

    [html] view plain copy
     print?
    1. # .bashrc  
    2.   
    3. # User specific aliases and functions  
    4.   
    5. alias rm='rm -i'  
    6. alias cp='cp -i'  
    7. alias mv='mv -i'  
    8.   
    9. # Source global definitions  
    10. if [ -f /etc/bashrc ]; then  
    11.         . /etc/bashrc  
    12. fi  

    c. /etc/bashrc文件

            /etc/bashrc又TM的做了什么事情?在/etc/bashrc文件中也做了两件事情,一件事情是定义了一些局部变量(没有export,登录shell可用,其fork的子shell均不能访问),还根据UID设置了umask的权限;另一件事情是又读取并执行了一次/etc/profile.d目录下的文件,这一步和启动shell有重复,虽然看似重复但实际上是有必要的原因,这里了需要和交互shell(下一节讲解)结合。

            至此,用户登录环境初始化完成,所有用户公共的全局变量有了,不同用户个性化的全局变量也准备好了,和自己有关系的局部变量也准备好了,万事俱备,用户可以进行系统操作了。

    [html] view plain copy
     print?
    1. # /etc/bashrc  
    2.   
    3. # System wide functions and aliases  
    4. # Environment stuff goes in /etc/profile  
    5.   
    6. # It's NOT a good idea to change this file unless you know what you  
    7. # are doing. It's much better to create a custom.sh shell script in  
    8. # /etc/profile.d/ to make custom changes to your environment, as this  
    9. # will prevent the need for merging in future updates.  
    10.   
    11. # are we an interactive shell?  
    12. if [ "$PS1" ]; then  
    13.   if [ -z "$PROMPT_COMMAND" ]; then  
    14.     case $TERM in  
    15.     xterm*)  
    16.         if [ -e /etc/sysconfig/bash-prompt-xterm ]; then  
    17.             PROMPT_COMMAND=/etc/sysconfig/bash-prompt-xterm  
    18.         else  
    19.             PROMPT_COMMAND='printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"'  
    20.         fi    
    21.         ;;    
    22.     screen)  
    23.         if [ -e /etc/sysconfig/bash-prompt-screen ]; then  
    24.             PROMPT_COMMAND=/etc/sysconfig/bash-prompt-screen  
    25.         else  
    26.             PROMPT_COMMAND='printf "\033]0;%s@%s:%s\033\\" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"'  
    27.         fi    
    28.         ;;    
    29.     *)    
    30.         [ -e /etc/sysconfig/bash-prompt-default ] && PROMPT_COMMAND=/etc/sysconfig/bash-prompt-default  
    31.         ;;    
    32.       esac  
    33.   fi    
    34.   # Turn on checkwinsize  
    35.   shopt -s checkwinsize  
    36.   [ "$PS1" = "\\s-\\v\\\$ " ] && PS1="[\u@\h \W]\\$ "  
    37.   # You might want to have e.g. tty in prompt (e.g. more virtual machines)  
    38.   # and console windows  
    39.   # If you want to do so, just add e.g.  
    40.   # if [ "$PS1" ]; then  
    41.   #   PS1="[\u@\h:\l \W]\\$ "  
    42.   # fi  
    43.   # to your custom modification shell script in /etc/profile.d/ directory  
    44. fi  
    45.   
    46. if ! shopt -q login_shell ; then # We're not a login shell  
    47.     # Need to redefine pathmunge, it get's undefined at the end of /etc/profile  
    48.     pathmunge () {  
    49.         case ":${PATH}:" in  
    50.             *:"$1":*)  
    51.                 ;;  
    52.             *)  
    53.                 if [ "$2" = "after" ] ; then  
    54.                     PATH=$PATH:$1  
    55.                 else  
    56.                     PATH=$1:$PATH  
    57.                 fi  
    58.         esac  
    59.     }  
    60.   
    61.     # By default, we want umask to get set. This sets it for non-login shell.  
    62.     # Current threshold for system reserved uid/gids is 200  
    63.     # You could check uidgid reservation validity in  
    64.     # /usr/share/doc/setup-*/uidgid file  
    65.     if [ $UID -gt 199 ] && [ "`id -gn`" = "`id -un`" ]; then  
    66.        umask 002  
    67.     else  
    68.        umask 022  
    69.     fi  
    70.   
    71.     # Only display echos from profile.d scripts if we are no login shell  
    72.     # and interactive - otherwise just process them to set envvars  
    73.     for i in /etc/profile.d/*.sh; do  
    74.         if [ -r "$i" ]; then  
    75.             if [ "$PS1" ]; then  
    76.                 . "$i"  
    77.             else  
    78.                 . "$i" >/dev/null 2>&1  
    79.             fi  
    80.         fi  
    81.     done  
    82.   
    83.     unset i  
    84.     unset pathmunge  
    85. fi  


    四、交互shell

            init 3登录系统之后,你在命令行界面输入的指令实际上都是在登录shell的环境中执行,你可以访问登录shell中声明的任意局部变量。但是当你输入bash显式启动一个交互shell的时候(命令行界面给你的感觉是敲了一下回车,剩下的好像什么也没发生),你会发现粗大事了,还是在一模一样的界面,但是你发现访问不了刚才可以访问到的局部变量了。这是因为登录shell fork了一个子shell的环境,而子shell环境是不能访问父shell环境的局部变量的。

    1. 区别登录shell和交互shell

            证明一:交互shell不是登录shell,而是登录shell fork的一个子shell进程

                    步骤一:登录系统后,定义一个局部变量testing="zhangsan",命令行输入echo $testing,测试可以访问得到;

                    步骤二:命令行输入bash启动一个交互shell,访问刚才定义的局部变量,echo $testing,测试不可以访问;

                    步骤三:命令行输入exit指令,退出交互式shell,再次访问echo $testing,发现可以访问;

    [html] view plain copy
     print?
    1. [work@localhost ~]$ testing="zhangsan"  
    2. [work@localhost ~]$ echo $testing  
    3. zhangsan  
    4. [work@localhost ~]$ bash  
    5. [work@localhost ~]$ echo $testing  
    6.   
    7. [work@localhost ~]$ exit  
    8. exit  
    9. [work@localhost ~]$ echo $testing  
    10. zhangsan  
    11. [work@localhost ~]$   
            由此可见,交互shell是登录shell的子进程。

    2. 交互shell详解

            当你在命令行输入bash指令显式进入交互式shell环境的时候,系统发生了什么?不像启动shell和登录shell,交互式shell没有发生在系统启动的时候,也没有发生在用户登录的时候,这时候系统已经启动,用户已经登录,之前的读取的文件执行的指令和结果都已经在内存中存在了,那么交互式shell做了那些事情呢?

            交互shell是登录shell的子进程,因此他拥有了登录shell声明的所有全局环境变量(当然也拥有启动shell声明的全局环境变量),但是他没有登录shell声明的局部变量,也没有登录shell声明的一些个性化例如umask、alias等,那么当前用户没有任何理由开启一个交互式shell,个性化丢失,每次开启都要重新搞一遍个性化,太TM麻烦了,这种功能你用吗?有毛用啊?

            请不要激动,存在即合理。

            交互式shell启动第一步,就是检查当前用户的主目录下是否有.bashrc文件(这个文件上一节有详细的描述),存在则读取并执行文件中的指令。这个文件的作用不就是声明局部变量和个性化配置的的吗?他第一步就是定义别名等,然后source /etc/bashrc文件,/etc/bashrc文件一开始定义了用户的局部变量,接着又加载并执行了/etc/profile.d目录下的应用启动文件。

            你会惊奇的发现,开启一个交互shell,和一个刚刚登录的登录shell环境一模一样!干净、纯粹、原始,就像少女一样啊!激动吧?!还有更激动的事情,不要忘了,子shell可以访问父shell的全局环境变量,但是父shell不能访问子shell的环境,也就意味着你在交互式shell中所做的坏事永远不会影响到父shell环境(当然你不要手贱去改配置文件,改了配置文件就是持久化了操作内容,而不是更改内存内容,系统断电后再启动加载文件还是会还原出来的),当然如果想父shell环境也能感受到,则需要修改文件了。

            实际上你也能感受到,登录shell其实就是第一个交互shell,一问一答,用户问系统答,很友好啊,有求必应!


    五、非交互shell

            非交互shell就没有那么友好了,这也正是非交互shell存在的核心价值,不需要用户来干预,自动完成脚本中规定的指令。

            因此,简单来说,非交互shell,即是执行shell脚本。

            当然,非交互式shell作为交互shell fork出来的子进程,拥有父进程所有的全局环境变量(再次申明:不拥有父进程的局部环境变量,你在脚本中是访问不到的),他不会再像交互shell那样到用户主目录下去读取执行.bashrc文件给自己做个性化,最简单直接的例子就是ls的alias指令ll,你在脚本中使用该指令,就会收到”run.sh: line 3: ll: command not found“的错误提示,如以下代码示例。

    [html] view plain copy
     print?
    1. [work@localhost env]$ alias -p |grep ll  
    2. alias ll='ls -l --color=auto'  
    3. [work@localhost env]$ cat run.sh   
    4. #!/bin/bash  
    5.   
    6. ll  
    7. [work@localhost env]$ sh run.sh   
    8. run.sh: line 3: ll: command not found  
    9. [work@localhost env]$ echo $?  
    10. 127  
    11. [work@localhost env]$ ll  
    12. total 16  
    13. drwxrwxr-x. 2 work work 4096 Apr 23 06:56 alias  
    14. drwxrwxr-x. 2 work work 4096 Apr 23 05:43 global  
    15. drwxrwxr-x. 2 work work 4096 Apr 23 05:59 local  
    16. -rw-rw-r--. 1 work work   16 Apr 23 07:59 run.sh  

            要想对非交互是shell进行个性化,系统也提供了”接口“,就是环境变量BASH_ENV,当启动一个非交互式shell的时候,系统会检查这个环境变量来查看要加载执行的启动文件,因此你可以自定义一个文件路径然后export BASH_ENV,从而达到你想要的目的和结果,这也是传说中的BASH_ENV漏洞,但是这个漏洞在2014.09月被修复了,在此就不再进行赘述了。

            1)BASH_ENV漏洞简单利用:点击打开链接

            2)BASH_ENV漏洞修复介绍:点击打开链接


    六、fork、source和exec

            shell编程的时候,往往不会把所有功能都写在一个脚本中,这样太不好维护了,需要多个脚本文件协同工作。那么问题来了,在一个脚本中怎么调用其他的脚本呢?有三种方式,分别是fork、source和exec。

    1. fork

            fork其实最麻烦,他是从当前shell进程中fork一个子shell进程来完成调用,上文所述的所有情况都是fork调用形式,简单总结,就是父shell进程的全局环境变量copy一份给子shell进程,因为是拷贝,所以子shell进程对这一份变量的所有操对父shell进程无影响,父进程的局部变量不会被子shell进程访问到;子shell的全局环境变量自对自己和自己的子shell进程有用,对父shell进程屏蔽,子shell的局部变量也只对当前shell进程有效。

            另外,fork调用其实就是在一个脚本中调用另一个脚本,被调用脚本执行完成之后返回给父shell进程,父shell进程继续执行剩下的指令,其中所涉及的庆幸上文已经基本全部覆盖,此处演示一下fork调用的示例代码。

    [html] view plain copy
     print?
    1. #!/bin/bash  
    2.   
    3. echo "父shell进程开始执行"  
    4. sh son.sh #父shell fork子shell环境执行另一个脚本  
    5. echo "父shell进程执行完毕"  
    [html] view plain copy
     print?
    1. #!/bin/bash  
    2.   
    3. echo "子shell被调用"  
    [html] view plain copy
     print?
    1. [work@localhost fork]$ sh father.sh   
    2. 父shell进程开始执行  
    3. 子shell被调用  
    4. 父shell进程执行完毕  



    2. source

            source调用,是把被调用脚本加载到当前的shell环境中来执行,就好像是在一个脚本里面运行一样,他们的定义的局部变量共享,在同一个进程中,如以下示例。

    [html] view plain copy
     print?
    1. #!/bin/bash  
    2.   
    3. . ./son.sh  #通过source方式将son.sh加载到当前shell环境中  
    4.   
    5. echo "father访问son中定义的局部变量:$sonVar"  
    [html] view plain copy
     print?
    1. #!/bin/bash  
    2.   
    3. sonVar="son var"  
    4. echo "son定义了一个变量:sonVar=$sonVar"  
    [html] view plain copy
     print?
    1. [work@localhost source]$ sh father.sh   
    2. son定义了一个变量:sonVar=son var  
    3. father访问son中定义的局部变量:son var  

    3. exec

            exec调用,也是fork一个子shell环境来执行被调用脚本,但是父shell环境的执行权会被剥夺,也就是执行权被交给了被调用脚本,父shell环境不再拥有执行权,无论父shell脚本中的指令是否执行完成,都不在被执行,随着子shell进程的结束而结束。

    [html] view plain copy
     print?
    1. #!/bin/bash  
    2.   
    3. echo "父shell开始执行"  
    4. exec sh son.sh  
    5. echo "父shell完成执行,但是这句话不会被执行"  
    [html] view plain copy
     print?
    1. #!/bin/bash  
    2.   
    3. echo "子shell被父shell exec调用,执行权已经被抢占过来了,不会在交回给父shell进程"  
    [html] view plain copy
     print?
    1. [work@localhost exec]$ sh father.sh   
    2. 父shell开始执行  
    3. 子shell被父shell exec调用,执行权已经被抢占过来了,不会在交回给父shell进程  

            关于fork、source和exec网上已经有很多介绍了,要是这里没有看明白,可以搜索“fork、source和exec”。


    七、环境变量PATH

            什么是环境变量PATH?这个环境变量,在调用shell脚本的时候很有用,麻烦和问题也主要集中在这里,PATH环境变量定义了各种shell环境搜索执行指令的路径,就像windows上的path环境变量一样。执行自己写的脚本,如果你不想进入到脚本目录或者输入全路径,那么你直接把你的脚本拷贝到PATH下面的任意一个目录即可,但是这样太侵入了,不优雅,下面简单介绍一种比较优雅的开发技巧。

    开发技巧:便捷执行指令

            通过软连接和别名alias来让自定义脚本可以在当前shell环境中任意被调用。

            第一步:查看PATH环境变量,随便选一个当前用户有操作权限的一个出来,本处选择/home/work/bin

            第二步:写一个测试脚本run.sh,放在/home/work/shell/myCodes目录下,里面只有一句指令”echo $0"打印当前执行脚本名称,然后做一个软连接ln -s /home/work/shell/myCodes/run.sh /home/work/bin/run

            第三步:定义别名,先alias -p看一下,不要定义重复了,然后定义别名alias run="sh run",完成

            结果:你不用在进入到脚本所在的目录执行脚本,在任意目录执行run指令就可以调用/home/work/shell/myCodes/run.sh脚本,而且支持tab键补全,是不是很NB!

    [html] view plain copy
     print?
    1. [work@localhost myCodes]$ ls  
    2. run.sh  
    3. [work@localhost myCodes]$ cat run.sh   
    4. #!/bin/bash  
    5.   
    6. echo $0  
    7. [work@localhost myCodes]$ pwd  
    8. /home/work/shell/myCodes  
    9. [work@localhost myCodes]$ cat run.sh   
    10. #!/bin/bash  
    11.   
    12. echo $0  
    13. [work@localhost myCodes]$ ll /home/work/bin/run    
    14. lrwxrwxrwx. 1 work work 31 Apr 23 09:57 /home/work/bin/run -> /home/work/shell/myCodes/run.sh  
    15. [work@localhost myCodes]$ alias -p |grep run  
    16. alias run='run'  
    17. [work@localhost myCodes]$ cd /home/work/  
    18. [work@localhost ~]$ run  
    19. i'm bash_env  
    20. /home/work/bin/run  


    附注:

            本文如有错漏,烦请不吝指正,谢谢!

    展开全文
  • Linux环境变量的设置

    万次阅读 2018-10-08 19:45:53
    Linux环境变量的设置 环境变量 在Windows 系统下,很多软件安装都需要配置环境变量,比如 安装 jdk ,如果不配置环境变量,在非软件安装的目录下运行javac 命令,将会报告找不到文件,类似的错误。 在Linux系统...

    目录

    环境变量

    Shell定义的环境变量

    查看环境变量

    Linux下环境变量的设置


    环境变量

    在Windows 系统下,很多软件安装都需要配置环境变量,比如 安装 jdk ,如果不配置环境变量,在非软件安装的目录下运行javac 命令,将会报告找不到文件,类似的错误。

    在Linux系统下,如果你下载并安装应用程序,很有可能在键入它的名称的时候出现 “command  not found ” 的提示内容。 如果每次都到安装目录文件夹内,找到可执行文件来进行操作就太繁琐了。 这涉及到环境变量path的设置问题,而path 的设置也是在Linux下定制环境变量的一个组成部分

    那么什么是环境变量?简单说,就是指定一个目录,运行软件的时候,相关的程序将会按照该目录寻找相关文件。 设置变量对于一般人最实用的功能就是: 不用拷贝某些dll文件到系统目录中了,而path 这一系统变量就是系统搜索dll文件的一系列路径

    Shell定义的环境变量

    Shell在开始执行的时候就已经定义了一些与系统工作环境有关的变量,用户还可以重新定义这些变量。 
    常用的shell环境变量有以下几种。 

    • HOME:用于保存用户主目录的完全路径名。 
    • PATH:用于保存用冒号分隔的目录路径名,shell将按PATH变量中给出的顺序搜索这些目录,找到的第一个与命令名称一致的可执行文件将被执行。 
    • SHELL:当前用户使用的Shell 
    • UID:当前用户的UID 
    • LOGNAME:当前用户的登录名 
    • HOSTNAME:主机名称

    查看环境变量

    Linux中set 、env 和 export 都可以查看环境变量

    • set命令显示当前shell的变量,包括当前用户的变量,set主要用来设置sh的参数与选项
    • env命令显示当前用户的变量,env用来在构建的环境中运行命令
    • export命令显示当前导出成用户变量的shell变量

    每个shell都有自己特有的变量(set)显示的变量,这个和用户变量是不同的,当前用户变量和你用什么shell无关,不管你用什么shell都在,比如HOME,SHELL等这些变量,

    但shell自己的变量不同,比如BASH_ARGC, BASH等,这些变量只有set才会显示,是bash特有的

    export不加参数的时候,显示哪些变量被导出成了用户变量,因为一个shell自己的变量可以通过 export “导出”变成一个用户变量。

    Linux下环境变量的设置

    如果想将一个路径加入到 $PATH 中,可以有几种方法

    比如我想将 /tmp/xie  路径加入到 $PATH 变量中

    1、控制台中设置 (只对当前shell有效)

    PATH=$PATH:/tmp/xie

    2、修改当前家目录下的 .bashrc 文件 (只对当前用户有效)

    vim   ~/.bashrc  ,在最末尾加入下面的 ,然后  source  .bashrc  或者  .  .bashrc

    export  PATH=$PATH:/tmp/xie

    3、修改/etc/bashrc 文件 (针对所有用户有效)

    vim  /etc/bashrc ,在最末尾加入下面的,然后  source  /etc/bashrc  或者  .  /etc/bashrc

    export  PATH=$PATH:/tmp/xie

    展开全文
  • Linux环境变量的设置和查看

    千次阅读 2018-03-16 11:35:20
    环境变量一般是指在操作系统中用来指定操作系统运行环境的一些参数,比如临时文件夹位置和系统文件夹位置等等。 一、Linux的变量种类 按变量的生存周期来划分,Linux变量可分为两类: 1、永久的:需要修改配置...

        环境变量一般是指在操作系统中用来指定操作系统运行环境的一些参数,比如临时文件夹位置和系统文件夹位置等等。

     一、Linux的变量种类

          按变量的生存周期来划分,Linux变量可分为两类:

          1、永久的:需要修改配置文件,变量永久生效。

          2、临时的:使用export命令声明即可,变量在关闭shell时失效。

     

    二、设置变量的三种方法

    1、在/etc/profile文件中添加变量【对所有用户生效(永久的)】

          用VI在文件/etc/profile文件中增加变量,该变量将会对Linux下所有用户有效,并且是“永久的”。

          例如:编辑/etc/profile文件,添加PATH变量

          # vi /etc/profile

           export  PATH=/home/fs : $PATH    

      注:修改文件后要想马上生效还要运行# source /etc/profile不然只能在下次重进此用户时生效。

         

    2、在用户目录下的.bash_profile文件中增加变量【对单一用户生效(永久的)】

          用VI在用户目录下的.bash_profile文件中增加变量,改变量仅会对当前用户有效,并且是“永久的”。

          例如:编辑guok用户目录(/home/guok)下的.bash_profile

          $ vi /home/guok/.bash.profile

          添加如下内容:

          export CLASSPATH=./JAVA_HOME/lib;$JAVA_HOME/jre/lib

          注:修改文件后要想马上生效还要运行$ source /home/guok/.bash_profile不然只能在下次重进此用户时生效。

     

    3、直接运行export命令定义变量【只对当前shell(BASH)有效(临时的)】

          在shell的命令行下直接使用[export 变量名=变量值]

          定义变量,该变量只在当前的shell(BASH)或其子shell(BASH)下是有效的,shell关闭了,变量也就失效了,再打开新shell时就没有这个变量,需要使用的话还需要重新定义。

     

    三、PATH声明,其格式为:

          PATH=$PATH:<PATH 1>:<PATH 2>:<PATH 3>:------:<PATH N>

          你可以自己加上指定的路径,中间用冒号隔开。环境变量更改后,在用户下次登陆时生效。

          如果想立刻生效,则可执行下面的语句:$source .bash_profile

          需要注意的是,最好不要把当前路径”./”放到PATH里,这样可能会受到意想不到的攻击。

          完成后,可以通过$ echo $PATH查看当前的搜索路径。这样定制后,就可以避免频繁的启动位于shell搜索的路径之外的程序了。

     

    四、常用的环境变量

      PATH      决定了shell将到哪些目录中寻找命令或程序

      HOME      当前用户主目录

      HISTSIZE 历史记录数

      LOGNAME   当前用户的登录名

      HOSTNAME 指主机的名称

      SHELL   当前用户Shell类型

      LANGUGE  语言相关的环境变量,多语言可以修改此环境变量

      MAIL   当前用户的邮件存放目录

      PS1   基本提示符,对于root用户是#,对于普通用户是$

     

    五、常用的环境变量相关命令
    1. 显示环境变量HOME
    1. fs@ubuntu:~$ echo $HOME  
    2. /home/fs  
    3. fs@ubuntu:~$   

    2. 设置一个新的环境变量hello
    1. fs@ubuntu:~$ export HELLO="Hello"  
    2. fs@ubuntu:~$ echo $HELLO  
    3. Hello  
    4. fs@ubuntu:~$   

    3. 使用env命令显示所有的环境变量

    1. fs@ubuntu:~$ env  
    2. SSH_AGENT_PID=2427  
    3. GPG_AGENT_INFO=/tmp/keyring-Sqfg93/gpg:0:1  
    4. TERM=xterm  
    5. SHELL=/bin/bash  
    6. XDG_SESSION_COOKIE=689f5a37acfced492491d99f00000008-1450313888.771442-154751925  
    7. HELLO=Hello  
    8. WINDOWID=62914565  
    9. OLDPWD=/home/fs/qiang/shell  
    10. GNOME_KEYRING_CONTROL=/tmp/keyring-Sqfg93  
    11. USER=fs  
    12. ....  


    4. 使用set命令显示所有本地定义的Shell变量 

    1. fs@ubuntu:~$ set  
    2. BASH=/bin/bash  
    3. BASH_VERSINFO=([0]="2"[1]="05b"[2]="0"[3]="1"[4]="release"[5]="i386-redhat-linux-gnu")  
    4. BASH_VERSION='2.05b.0(1)-release'  
    5. COLORS=/etc/DIR_COLORS.xterm  
    6. COLUMNS=80  
    7. DIRSTACK=()  
    8. DISPLAY=:0.0  
    9.   
    10. ...  

    5. 使用unset命令来清除环境变量

    set可以设置某个环境变量的值。清除环境变量的值用unset命令。如果未指定值,则该变量值将被设为NULL。示例如下:

    1. fs@ubuntu:~$ export TEST="Test" \\增加一个环境变量TEST  
    2. fs@ubuntu:~$ env | grep TEST \\此命令有输出,证明环境变量TEST已存在  
    3. TEST=Test  
    4. fs@ubuntu:~$ unset $TEST \\删除环境变量TEST  
    5. fs@ubuntu:~$ env | grep TEST \\此命令没输出,证明环境变量TEST已经存在了  
    6.   
    7.      

    6. 使用readonly命令设置只读变量

    如果使用了readonly命令的话,变量就不可以被修改或清除了。示例如下:

    1. fs@ubuntu:~$ export TEST="Test" \\增加一个环境变量TEST  
    2. fs@ubuntu:~$ readonly TEST \\将环境变量TEST设为只读  
    3. fs@ubuntu:~$ unset TEST \\此变量无法删除  
    4. bash: unset: TEST: cannot unset: readonly variable  
    5. fs@ubuntu:~$ TEST="NEW" \\此变量不可更改  
    6. bash: TEST: readonly variable  
    7. fs@ubuntu:~$   
    展开全文
  • 环境变量:定义每个用户的操作环境 1. Source命令:修改配置文件后,必须注销重新登录才能生效,使用source命令后,立即生效环境变量配置文件; 命令如下:source 配置文件  或者 . 配置文件 2. 环境变量...
  • Linux添加环境变量

    万次阅读 2019-06-03 15:05:41
    linux添加环境变量分为两种情况: 临时变量,指当shell窗口关闭时变量失效,通过export命令添加 全局生效,修改/etc/profile文件,这样环境变量全局生效且不会因窗口的关闭而失效。 1.查看当前环境变量 echo $PATH...
  • Linux环境变量

    千次阅读 多人点赞 2018-07-02 23:52:59
    1、环境变量的概念 ...在Linux中的变量,可以分为环境变量和本地变量: 1)环境变量:相当于全局变量,存在于所有的Shell中,具有继承性; 2)本地变量:相当于局部变量只存在当前Shell中,本地...
  • Linux下修改环境变量

    千次阅读 2019-03-30 21:46:44
    刚接触Linux,记录一下Linux下修改环境变量的过程。 首先切换到root用户。 (1)打开profile文件 ①通过vim打开 vim /etc/profile ②通过文本编辑器打开 gedit /etc/profile (2)编辑和保存profile文件 ...
  • Linux环境变量文件介绍

    万次阅读 多人点赞 2018-08-11 13:18:38
    Linux系统中,环境变量按照其作用范围不同大致可以分为系统级环境变量和用户级环境变量。  系统级环境变量:每一个登录到系统的用户都能够读取到系统级的环境变量  用户级环境变量:每一个登录到系统的用户只...
  • Linux配置Java环境变量

    万次阅读 2019-07-30 15:53:38
    1、将免安装的JDK拷贝到...2、更改环境变量 vim /etc/profile 加入如下代码: export JAVA_HOME=/usr/local/jdk1.8.0_144 export PATH=.:$JAVA_HOME/bin:$PATH export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JA...
  • Linux配置完环境变量立即生效

    万次阅读 2017-11-07 21:44:07
    source /etc/profile
  • linux环境变量和Windows的环境变量一样,分系统环境变量和用户环境变量,系统环境变量对所有用户有效,而用户环境变量只对当前用户有效,下面以jdk为例进行两种环境变量的配置。 1.系统环境变量配置 执行 vim /etc/...
  • Linux中修改环境变量及生效方法(永久、临时)环境变量查看 https://blog.csdn.net/u011630575/article/details/49839893
  • Linux设置全局环境变量的三种方法

    万次阅读 2014-10-23 11:09:52
     1.1 :首先在此文件中设置环境变量;  1.2:export 设置好的环境变量.  #vim /etc/profile 2、修改.bashrc # vim /root/.bashrc export PATH="变量路径" 3、直接在shell下用export命令修改  #...
  • 这是因为用户的家目录中有一个隐藏文件.bash_profile,里面有用户的环境变量修改方法:然后source ~/.bash_profile再尝试自己的命令就可以了
  • linux 刷新环境变量

    万次阅读 2017-11-17 11:27:33
    linux 刷新环境变量
  • linux 安装nodejs及配置环境变量

    万次阅读 2018-05-23 12:06:36
    下载到nodejs官方网站下载nodejs 官网地址 https://nodejs.org解压 tar -xvf node-v8.11.2-linux-x64.tar 配置环境变量vim .bash_profile(我这里配置局部变量,vim /etc/profile 全局变量)export NODE_HOME=/...
  • Linux设置anaconda的环境变量

    万次阅读 2017-08-15 14:31:56
    由于实验的GPU服务器上放了很多版本的python,而我需要用到的只是anaconda的python,所以就需要修改一下环境变量 这里参考了这个点击打开链接。 1.修改~/.bashrc 2.添加export PATH=/home/lishanliao/anaconda3/bin ...
  • 环境变量是一个具有特定名字的对象,它包含了一个或者多个应用程序所将使用到的信息。例如PATH.在交叉编译中,会经常运用到环境变量的设置。 查看当前全部的环境变量的命令是env.  查看环境变量的值是echo +$...
  • 【Python】linux下添加Python环境变量

    千次阅读 2018-10-09 10:02:07
    永久性添加: https://blog.csdn.net/idKevin/article/details/78524226
1 2 3 4 5 ... 20
收藏数 537,193
精华内容 214,877
关键字:

linux环境变量