为什么我可以在任何地方执行ls这个指令呢?

为什么我在任何目录下输入 ls 就一定可以显示出一些讯息而不会说找不到该指令呢? 这是因为环境变数 PATH 的帮助。

当我们在执行一个指令的时候,举例来说ls好了,系统会依照PATH的设定去每个PATH定义的目录下搜寻档名为ls的可执行文件, 如果在PATH定义的目录中含有多个档名为ls的可执行文件,那么先搜寻到的同名指令先被执行

看看到底有哪些目录被定义出来了?

1
2
3
4
5
  [root@LuffyCity ~]# echo $PATH
  /usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
  [root@LuffyCity ~]# su - luffy
  [luffy@manage01 ~]$ echo $PATH
  /usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/luffy/.local/bin:/home/luffy/bin

PATH(一定是大写)是由一堆目录所组成的,每个目录中间用冒号:来隔开,每个目录是有顺序之分的。

仔细看一下上面的输出,妳可以发现到无论是root还是dmtsai都有 /bin/usr/bin 这个目录在PATH变量内,所以当然就能够在任何地方执行ls来找到/bin/ls执行档!因为 /binCentOS 7 当中,就是连结到 /usr/bin 去的! 所以这两个目录内容会一模一样!

我们用几个范例来让你瞭解一下,为什么PATH是那么重要的项目!

例1:如何设定默认路径

例题:

假设你是root,如果你将ls/bin/ls移动成为/root/ls(可用mv /bin/ls /root指令达成),然后你自己本身也在/root目录下, 请问:

  1. 你能不能直接输入ls来执行?
  2. 若不能,你该如何执行ls这个指令?
  3. 若要直接输入ls即可执行,又该如何进行?

答:

我们先将ls文件移动到 /root

1
[root@LuffyCity ~]# mv /bin/ls /root

接下来不论你在那个目录底下输入任何与ls相关的指令,都没有办法顺利的执行ls了! 因为PATH对应的目录下没有ls可执行文件

但是这个ls确实存在于/root底下!所以我们可以透过使用绝对路径或者是相对路径直接指定这个文件,底下的两个方法都能够执行ls这个指令:

1
2
  [root@LuffyCity ~]# /root/ls  <==直接用绝对路径指定该档名
  [root@LuffyCity ~]# ./ls      <==因为在 /root 目录下,就用./ls来指定

如果想要让root在任何目录均可执行/root底下的ls,那么就将/root加入PATH当中即可。就像底下这样:

1
  [root@LuffyCity ~]# PATH="${PATH}:/root"

如果确定这个例题进行没有问题了,请将ls搬回/bin底下,不然系统会挂掉的!

1
  [root@study ~]# mv /root/ls /bin

某些情况下,即使你已经将 ls 搬回 /bin 了,不过系统还是会告知你无法处理 /root/ls 喔!很可能是因为指令参数被快取的关系。只要登出 (exit) 再登入 (su -) 就可以继续快乐的使用 ls 了!

例2: 路径的优先顺序

例题:

如果我有两个ls指令在不同的目录中,例如/usr/local/bin/ls/bin/ls那么当我下达 ls 的时候,哪个ls会被执行?

答: 那还用说,就找出 ${PATH} 里面哪个目录先被查询,则那个目录下的指令就会被先执行了!所以用 dmtsai 帐号为例,他最先搜寻的是 /usr/local/bin, 所以 /usr/local/bin/ls 会先被执行!

例3: 将当前目录加入PATH

例题:

为什么 ${PATH} 搜寻的目录不加入本目录(.)?加入本目录的搜寻不是也不错?

答:

如果在PATH中加入本目录(.)后,确实我们就能够在指令所在目录进行指令的执行了。但是由于你的工作目录并非固定(常常会使用cd来切换到不同的目录), 因此能够执行的指令会有变动(因为每个目录底下的可执行档都不相同嘛!),这对使用者来说并非好事。

另外,如果有个坏心使用者在/tmp底下做了一个指令,因为/tmp是大家都能够写入的环境,所以他当然可以这样做。 假设该指令可能会窃取使用者的一些资料,如果你使用root的身份来执行这个指令,那不是很糟糕?如果这个指令的名称又是经常会被用到的ls时,中标的机率就更高了!

所以,为了安全起见,不建议将.加入PATH的搜寻目录中。

小结

而由上面的几个例题我们也可以知道几件事情:

  • 不同身份使用者预设的PATH不同,预设能够随意执行的指令也不同(如rootdmtsai);
  • PATH是可以修改的;
  • 使用绝对路径或相对路径直接指定某个指令的档名来执行,会比搜寻PATH来的正确;
  • 指令应该要放置到正确的目录下,执行才会比较方便;
  • 本目录(.)最好不要放到PATH当中。

参考文献