环境变量

环境变量

变量

  • 在Shell中创建一个变量可以使用declare命令,但并非任何形式的变量名都是可用的,变量名只能是由英文字母、数字或者下划线组成,且不能由数字开头。比如创建一个tmp变量:

    1
    declare tmp
  • 使用=运算符为变量赋值:

    1
    tmp=shiyanlou
  • 使用echo$符号可以查看变量的值:

    1
    echo $tmp

    image-20231008230724020

环境变量

  • 环境变量的作用域比自定义变量要大,比如Shell的环境变量作用于自身和它的子进程

  • 有三个和环境变量相关的命令,setenvexport。这三个命令很相似,都是用于打印环境变量信息,区别在于涉及的变量范围不同。

命令 说明
set 显示当前Shell所有变量,包括内建环境变量、用户自定义变量及导出的环境变量
env 显示与当前用户相关的环境变量,还可以让命令在指定环境中运行
export 显示从Shell中导出成环境变量的变量,能通过它将自定义变量导出为环境变量

img

  • export来体验一下环境变量与普通变量的,先在Shell中设置一个变量temp=shiyanlou,然后创建一个子Shell查看temp变量的值:

    1
    2
    3
    4
    5
    6
    7
    8
    temp=shiyanlou
    echo $temp
    zsh
    echo $temp
    exit
    export temp
    zsh
    echo $temp

    image-20231008230934536

  • 通常为了与普通变量区分,习惯将环境变量名都设为大写

永久生效

  • 在关机之后,或者关闭shell,环境变量就会消失,可以将变量写入存放变量的文件中:/etc/bashrc/etc/profile,分别存放的是shell变量和环境变量,或者用户目录下的隐藏文件.profile,仅对当前用户生效,可以使用ls -a查看:

    1
    2
    cd ~
    ls -a

    .profile文件

命令的查找路径与顺序

  • 在Shell中命令的执行是通过环境变量PATH搜索的,查看PATH环境变量的内容:

    1
    echo $PATH

    image-20231008231225585

  • 系统会从PATH中以此查找,如果存在相同的命令,则执行先找到的那个

  • 接下来创建一个最简单的可执行Shell脚本和使用C语言创建的程序:

    • 在家目录创建一个mybin目录:

      1
      2
      cd ~
      mkdir mybin

      image-20231008231345401

    • 进入新创建的目录,创建一个Shell脚本文件并编辑:

      1
      2
      3
      cd mybin
      touch hello_shell.sh
      gedit hello_shell.sh

      如果遇到gedit提示:[Unable to init server: 无法连接: 拒绝连接],可以使用如下命令解决:

      1
      2
      export DISPLAY=localhost:1
      xhost local:gedit

      若出现以下内容,表示问题解决:

      1
      non-network local connections being added to access control list

      若还无法解决,可以使用vim编辑器

      1
      vim hello_shell.sh
    • 在脚本中写入如下内容(第一行不可省略):

      1
      2
      3
      4
      5
      6
      7
      #!/bin/bash

      for ((i=0; i<10; i++));do
      echo "hello shell"
      done

      exit 0
    • 为文件添加可执行权限:

      1
      chmod 755 hello_shell.sh
    • 执行脚本:

      1
      ./hello_shell.sh

      image-20231008233557594

    • 创建一个C语言程序并编辑:

      1
      2
      touch hello_world.c
      gedit hello_world.c
    • 写入如下内容:

      1
      2
      3
      4
      5
      6
      #include <stdio.h>

      int main(void){
      printf("hello world!\n");
      return 0;
      }
    • 然后使用gcc生成可执行文件:

      1
      gcc -o hello_world hello_world.c
    • 运行程序:

      1
      ./hello_world

      image-20231008233742246

  • 在返回到家目录后,如果再想运行刚才创建的两个程序,会提示命令找不到,除非加上命令的完整路径。如果希望可以像执行系统命令一样执行运行刚才创建的程序,可以将脚本文件添加到PATH环境变量中。

添加自定义路径到PATH环境变量

  • PATH路径是以:作为分隔符的,如果希望将上面的mybin目录加入PATH路径,则需要写入以下信息:

    1
    PATH=$PATH:/home/shiyanlou/mybin
  • 需要注意的是,这里一定要使用绝对路径

  • 那么现在就可以直接执行写下的两个命令了:

    1
    2
    hello_shell.sh
    hello_world

    image-20231008233916073

  • 但给PATH追加一条路径只会在当前Shell有效,一旦退出终端,再打开就会发现又失效了,那么可以利用用户home目录中一个在启动shell时自动运行的脚本。zsh的配置文件为.zshrc,相应Bash的配置文件为.bashrc,使用命令将路径添加到.zshrc中:

    1
    echo "PATH=$PATH:/home/shiyanlou/mybin" >> .zshrc

    上面命令中的>>表示将标准输出以追加的方式重定向到一个文件中。

修改和删除已有变量

变量修改

  • 变量修改有如下几种方式:
变量设置方式 说明
${变量名#匹配字串} 从头向后开始匹配,删除符合匹配字串的最短数据
${变量名##匹配字串} 从头向后开始匹配,删除符合匹配字串的最长数据
${变量名%匹配字串} 从尾向前开始匹配,删除符合匹配字串的最短数据
${变量名%%匹配字串} 从尾向前开始匹配,删除符合匹配字串的最长数据
${变量名/旧的字串/新的字串} 将符合旧字串的第一个字串替换为新的字串
${变量名//旧的字串/新的字串} 将符合旧字串的全部字串替换为新的字串
  • 比如要修改前面添加到PATH的环境变量,为了避免误操作导致命令找不到,我们先将PATH赋值给一个新定义的自定义变量:

    1
    2
    3
    4
    path=$PATH
    echo $path
    path=${path%/home/shiyanlou/mybin}
    path=${path%*/mybin}

删除变量

  • 可以使用unset命令删除一个环境变量:

    1
    unset temp

让环境变量立刻生效

  • 在Shell中修改了一个配置脚本文件后,必须要退出终端重新启动才可以生效,如果希望立即生效,可以使用source命令:

    1
    2
    cd ~
    source .zshrc
  • source命令还有一个别名.,或者使用以下方式:

    1
    2
    cd ~
    . ./.zshrc

搜索文件

whereis

  • whereis搜索很快,因为并没有从硬盘中依次查找,而是从数据库中查询

  • whereis只能搜索二进制文件(-b)、man帮助文件(-m)和源代码文件(-s)

    1
    2
    whereis who
    whereis find

    image-20231008234411280

locate

  • 通过/var/lib/mlocate/mlocate.db数据库查找,但这个文件只会由系统每天自动执行updatedb命令更新一次

  • 查找/usr/share/下的所有jpg文件:

    1
    2
    3
    sudo apt-get update
    sudo apt-get install locate
    locate /usr/share/\*.jpg
  • 如果只想统计数目可以加上-c参数,忽略大小写查找使用-i参数

which

  • which本身是Shell内建的一个命令,通常用来确定是否安装了某个指定的软件,因为其只通过PATH环境变量指定的路径中查找:

    1
    which man

find

  • find命令是四种查找中最强大的,格式为find [path] [option] [action]

  • 表示去 /etc/ 目录下面 ,搜索名字叫做 interfaces 的文件或者目录:

    1
    sudo find /etc/ -name interfaces

实战训练

  • 找出 /etc/ 目录下的所有以 .list 结尾的文件。

    1
    sudo find /etc/ -name \*.list 

    image-20231008234711794