Contents
  1. 1. 一、变量
    1. 1.1. 变量的声明、赋值与读取
  2. 2. 二、环境变量
    1. 2.1. 相关命令
    2. 2.2. 添加自定义路径到”PATH”环境变量
      1. 2.2.1. 变量删除
    3. 2.3. 如何让环境变量立即生效
  3. 3. 三、搜索文件
    1. 3.1. whereis简单快速
    2. 3.2. locate快而全
    3. 3.3. which小而精
    4. 3.4. find精而细

一、变量

变量的声明、赋值与读取

使用declare命令创建一个变量,例如创建一个变量名为tmp的变量

1
$ declare tmp

变量的赋值

1
$ tmp=shiyanlou

读取变量的值,使用echo命令和$符号($符号用于表示引用一个变量的值

1
$ echo $tmp

注意!变量名只能是英文字母,数字或者下划线,且不能以数字作为开头!

二、环境变量

shell的环境变量作用于自身和它的子进程。在所有的Unix和类Unix系统中,每个进程都有其各自的环境变量设置,且默认情况下,当一个进程被创建时,处理创建过程中明确指定的话,它将继承其父进程的绝大部分环境设置。shell程序也作为一个进程运行在操作系统之上,而我们在shell中运行的大部分命令都将以shell的子进程的方式运行。

进程演示图

相关命令

三种环境变量相关的命令,set,env,export

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

可以通过以下测试体会环境变量和普通变量的区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ temp=shiyanlou
$ echo $temp
shiyanlou
$ zsh //创建一个子shell,在ubuntu中默认shell为bash
$ echo $temp
//显示空
$ exit //推出子shell
$ export temp //把temp变量导出为环境变量
$ zsh //重新创建子shell
$ echo $temp
shiyanlou

!!!注意!!! 为了与普通变量区分,通常我们习惯将环境变量名设为大写

##命令的查找路径与顺序

我们在hell中输入一个命令,shell是怎么知道在哪去找到这个命令然后执行的呢。这是通过环境变量PATH来进行搜索的。这个PATH里面就保存了shell中执行的命令的搜索路径。

查看PATH环境变量的内容

1
$ echo $PATH

默认情况下你会看到如下输出

1
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

通常这一类目录下放的都是可执行文件,当我们在shell中执行一个命令时,系统就会按照PATH中设定的路径按照顺序依次到目录中去查找,如果存在同名的命令,则执行先找到的那个。下面我们将练习创建一个最简单的可执行shell脚本和一个使用C语言创建的”hello world”程序。

创建一个shell脚本文件

1
$ vim hello_shell.sh

在脚本中添加如下内容,保存并退出

1
2
3
4
5
6
7
#!/bin/zsh
for ((i=0; i<10; i++));do
echo "hello shell"
done
exit 0

为文件添加可执行权限

1
$ chmod 755 hello_shell.sh

创建一个c语言”hello world”程序:

1
$ vim hello_world.c
1
2
3
4
5
6
7
#include <stdio.h>
int main(void)
{
printf("hello world!\n");
return 0;
}

使用gcc生成可执行文件

1
$ gcc -o hello_world hello_world.c

在shiyanlou家目录创建一个mybin目录,并将上述hello_shell.sh和hello_world文件移动到其中

1
2
$ mkdir mybin
$ mv hello_shell.sh hello_world mybin/

现在你可以在mybin目录中分别运行你刚刚创建的两个程序

1
2
3
$ cd mybin
$ ./hello_shell.sh
$ ./hello_world

然后你回到上一级目录,也就是shiyanlou家目录,你再想运行那两个程序,会发现提示命令找不到,除非你加上命令的完整路径,但是这样不是很麻烦嘛,如何做到想使用系统命令一样执行自己创建的脚本文件或者程序呢。那就要将命令所在路径添加到PATH环境变量了。

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

在前面我们应该注意到PATH里面的路径是以:作为分割符,所以我们可以这样添加自定义路径

1
$ PATH=$PATH:/home/shiyanlou/mybin

!!!注意这里一定要使用绝对路径

现在你就可以在其他任意目录执行那两个命令了。你可能会意识到这样还并没有很好的解决问题,因为我给PATH环境变量追加了一个路径,它也只是在当前shell有效,我一旦退出终端,再打开就会发现又失效了。有没有方法让添加的环境变量全局有效又或者每次启动shell时自动执行上面添加自定义路径到PATH的命令了。下面我们就来说说后一种方式——让它自动执行。

在每个用户的家目录中有一个shell每次启动时会默认执行一个配置脚本,以初始化环境,包括添加一些用户自定义环境变量等等。zsh的配置文件是.zshrc,相应bash的配置文件为.bashrc。它们在etc下还都有一个或多个全局的配置文件,不过我们一般只修改用户目录下的配置文件。

我们可以简单的使用下面命令直接添加内容到.zshrc中

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

上述命令中 >>表示将标准输出以追加的方式重定向到一个文件中,注意前面用到的 >是以覆盖的方式重定向到一个文件中,使用的时候一定要注意分辨。在指定文件不存在的情况下都会创建新的文件

##修改和删除已有的变量

###变量的修改

变量的修改有以下几种方式:

变量设置方式 说明
${变量名#匹配字串} 从头向后开始匹配,删除符合匹配字串的最短数据
${变量名##匹配字串} 从头向后开始匹配,删除符合匹配字串的最长数据
${变量名%匹配字串} 从尾向前开始匹配,删除符合匹配字串的最短数据
${变量名%%匹配字串} 从尾向前开始匹配,删除符合匹配字串的最长数据
${变量名/旧的字串/新的字串} 将符合旧字串的第一个字串替换为新的字串
${变量名//旧的字串/新的字串} 比如要修改我们前面添加到PATH的环境变量:

比如修改我们前面添加到PATH的环境变量

为了避免操作失误导致命令找不到,我们先将PATH赋值给一个新的自定义变量path将符合旧字串的全部字串替换为新的字串

1
2
3
4
5
$ path=$PATH
$ echo $path
$ path=${path%/home/shiyanlou/mybin}
# 或使用通配符,*表示任意多个任意字符
$ path=${path%*/mybin}

变量删除

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

1
$ unset temp

如何让环境变量立即生效

在上面我们在shell中修改了一个配置脚本文件之后(比如zsh的配置文件home目录下的.zshrc),每次都要退出终端重新打开甚至重启主机之后其才能生效,很是麻烦,我们可以使用source命令来让其立即生效。

例如

1
$ source .zshrc

source命令还有一个别名就是.,注意与表示当前路径的那个点区分开,虽然形式一样,但作用和使用方式一样,上面的命令如果替换成.的方式就该是

1
$ . ./.zshrc

注意第一个点后面有一个空格,而且后面的文件必须指定完整的绝对或相对路径名,source则不需要

三、搜索文件

与搜索相关的命令常用的有如下几个whereis,which,find,locate

whereis简单快速

很快,它快是因为它并没有从硬盘老老实实挨个去找,而是直接从数据库中查询。whereis只能搜索二进制文件(-b),man帮助文件(-m)和源代码文件(-s)。

locate快而全

查找/etc下所有以sh开头的文件

1
$ locate /etc/sh

注意,它不只是在etc目录下查找并会自动递归子目录进行查找

查找/usr/share/下所有jpg文件

1
$ locate /usr/share/\*.jpg

注意要添加*号前面的反斜杠转义,否则会无法找到

如果想只统计数目可以加上-c参数,-i参数可以忽略大小写进行查找,whereis的-b,-m,-s同样可以是使用

which小而精

which本身是shell内建的一个命令,我们通常使用which来确定是否安装了某个指定的软件,因为它只从PATH环境变量指定的路径中去搜索命令

find精而细

find应该是这几个命令中最强大的了,它不但可以通过文件类型、文件名进行查找而且可以根据文件的属性(如文件的时间戳,文件的权限等)进行搜索。find命令强大到,要把它将明白至少需要单独好几节课程才行,我们这里就只介绍一些常用的内容

在指定目录下搜索指定文件名的文件

1
$ find /etc/ -name interfaces

注意find命令的路径是作为第一个参数的, 基本命令格式为 find [path] [option] [action]

与时间相关的命令参数

参数 说明
-atime 最后访问时间
-ctime 创建时间
-mtime 最后修改时间

下面以-mtime参数举例

  • -mtime n: n 为数字,表示为在n天之前的”一天之内“修改过的文件
  • -mtime +n: 列出在n天之前(不包含n天本身)被修改过的文件
  • -mtime -n: 列出在n天之前(包含n天本身)被修改过的文件
  • newer file: file为一个已存在的文件,列出比file还要新的文件名

时间轴

列出home目录中,当天(24小时之内)有改动的文件

1
$ find ~ -mtime 0

列出比某个文件新的所有文件

1
2
# 姑且利用一下工程师配置环境时遗留的test.c~文件吧-_-||
$ find ~ newer Documents/test.c\~
Contents
  1. 1. 一、变量
    1. 1.1. 变量的声明、赋值与读取
  2. 2. 二、环境变量
    1. 2.1. 相关命令
    2. 2.2. 添加自定义路径到”PATH”环境变量
      1. 2.2.1. 变量删除
    3. 2.3. 如何让环境变量立即生效
  3. 3. 三、搜索文件
    1. 3.1. whereis简单快速
    2. 3.2. locate快而全
    3. 3.3. which小而精
    4. 3.4. find精而细