4、第一个自定义命令:用Shell脚本创建hello命令,理解执行权限与PATH

好,咱们开始动手了。

前面讲了那么多概念,什么自定义命令、环境变量、PATH……说实话,光听不练容易晕。我个人习惯是,先搞一个最简单的例子跑起来,然后再回头理解那些理论,会轻松很多。

这一章的目标很明确:创建一个叫 hello 的命令,在终端里输入 hello 就能打印出一句问候。听起来简单?嗯,但这里面藏着两个关键知识点——执行权限和PATH。搞懂了它们,你才算真正入门了自定义命令。

4.1 先写一个Shell脚本

打开你的终端,随便找个目录,比如 ~/projects。创建一个文件,就叫 hello.sh:

touch hello.sh

然后用你喜欢的编辑器打开它,写入以下内容:

#!/bin/bash
echo "Hello, World! 这是我的第一个自定义命令。"

第一行 #!/bin/bash 叫 shebang,说白了就是告诉系统:「喂,用 Bash 解释器来跑这个文件」。没有这行,系统不知道拿什么来执行它。

第二行就是打印一句话,没什么好说的。

小提示: 文件名不一定非要带 .sh 后缀。Linux 不看后缀,只看文件内容。但加上后缀方便你自己识别,我建议保留。

4.2 执行权限——为什么不能直接跑?

现在试试运行它:

./hello.sh

你大概率会看到:

bash: ./hello.sh: Permission denied

为什么会这样?

因为新创建的文件默认没有执行权限。你可以用 ls -l 看看:

ls -l hello.sh

输出大概是:

-rw-r--r--  1 user  staff  58 Mar 10 10:00 hello.sh

看到最前面的 -rw-r--r-- 了吗?r 表示读权限,w 表示写权限,但没有 x(执行权限)。所以系统拒绝执行。

解决方式很简单,加上执行权限:

chmod +x hello.sh

再 ls -l 看看:

-rwxr-xr-x  1 user  staff  58 Mar 10 10:00 hello.sh

多了三个 x。现在再运行:

./hello.sh

应该能看到输出了。

注意: 我曾经见过有人把 chmod 777 当成万能药。千万别这么干!777 意味着任何人都有读、写、执行权限,这是安全大忌。用 chmod +x 就够了,只给执行权,不改读写权限。

4.3 去掉 ./——理解 PATH

现在你只能在当前目录下用 ./hello.sh 来运行。但真正的命令,比如 ls、cd,在任何目录下都能直接敲。为什么?

因为系统会在 PATH 环境变量里列出的目录中寻找命令。你可以看看自己的 PATH:

echo $PATH

输出类似:

/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

看到了吗?当前目录 . 并不在其中。所以系统找不到你的 hello.sh。

解决办法有两个:

  1. 把脚本放到 PATH 中的某个目录,比如 /usr/local/bin。
  2. 把当前目录加入 PATH,但不推荐,有安全风险。

我建议用第一种。把脚本复制过去:

sudo cp hello.sh /usr/local/bin/hello

注意,我顺便把文件名改成了 hello,去掉了 .sh 后缀。这样用起来更像一个命令。

现在,在任何目录下输入 hello:

hello

搞定!

核心总结: 一个文件要成为「命令」,需要满足两个条件:
1. 有执行权限(chmod +x)
2. 所在目录在 PATH 中(或者用绝对/相对路径调用)

4.4 避坑指南——我踩过的几个坑

讲几个我实际遇到过的问题,你遇到了别慌:

  • 坑一: 复制到 /usr/local/bin 后还是提示 command not found。检查一下 /usr/local/bin 是否在你的 PATH 里。有些系统默认不包含它。
  • 坑二: 脚本里用了 #!/bin/bash,但你的系统 Bash 路径不同。用 which bash 确认一下。
  • 坑三: 权限加上了,但运行时报 bad interpreter。多半是 shebang 写错了,比如 #!/bin/bash 写成了 #!/bin/bash (多了空格)。

嗯,这些坑我都踩过。尤其是第一个,当年我折腾了半小时才发现是 PATH 没配好。

4.5 进阶:让脚本接受参数

光打印固定文字太单调了。咱们让 hello 命令能接受一个名字参数:

#!/bin/bash
if [ -z "$1" ]; then
    echo "Hello, World!"
else
    echo "Hello, $1!"
fi

现在试试:

hello
hello 张三

输出:

Hello, World!
Hello, 张三!

是不是有点意思了?$1 就是第一个参数。你可以继续加 $2、$3……

4.6 本章小结

咱们这一章干了三件事:

  1. 写了一个简单的 Shell 脚本
  2. 加了执行权限,理解了 chmod +x
  3. 把脚本放到 PATH 目录下,让它变成全局命令

说白了,自定义命令没那么神秘。就是一个有执行权限的脚本文件,放在系统能找到的地方。你想想看,那些 ls、grep 本质上也是一个个可执行文件,只不过它们是用 C 语言写的,编译好了放在那里。

下一章,咱们会深入 PATH 的配置,教你怎么把自己的目录加进去,以及如何管理多个自定义命令。