初学者在接触命令行的时候,肯定会经常碰到command not found
这样的提示,有些时候可能会因此困惑,我明明是有这个文件的,但是为什么找不到命令呢
windows or *nix
windows下的命令行用起来的感觉差强人意,如果使用命令行还是使用*nix(linux,unix)比较好,这里默认使用linux的bash来进行解释
shell运行命令的方式
在bash
中,有四种命令可以在终端执行,分别是函数和别名
,内建命令
,外部命令
,以及可执行文件
在windows下的可执行文件是以.exe .bat .sh后缀名结尾的文件,但是在linux下任何文件只要有
x
可执行权限都可以执行 (x
可执行权限表现为使用ls -al
命令中出现为最前面的十个字符,分别表示文件类型
拥有者权限
用户组全选
其他用户权限
)
函数和别名
在终端下可以通过在shell的配置文件中编写函数来作为命令使用,比如在homestead
虚拟机中有一个函数artisan
,使用type artisan
可以看到artisan
的代码
默认的shell文件是/etc/profile 和.profile,而bash的默认配置文件则是/etc/bash.bashrc和.brshrc,其中etc目录下的是全局配置文件, .号开头的是用户专属配置文件
artisan()
{
php artisan "$@"
}
当使用artisan
命令的时候,shell会调用php去执行当前目录下的artisan文件,并把所有的参数一起传递过去,通过这个函数,就可以让我们不用每次都输入php artisan "arguments"
来工作了
还有一种是别名,比如ll
命令,通过内建命令alias
命令可以创建别名,比如使用type ll
的时候,就可以很清晰的看到
ll is aliased to `ls -alF'
内建命令
内建命令其实就是shell本身中已经编写好的指令,这些指令通常是不能用which
查看到的,比如cd
history
命令等,在命令行使用type
命令可以看到一个命令是什么类型的命令,比如使用
type history
就能看到输出 history 是shell 内建
history 显示当前用户使用过的所有的命令记录
外部命令
那么接下来外部命令是什么?
在解释外部命令之前,先引入一个词汇环境变量
,你应该或多或少的听过它的另一个命令PATH
,在终端下输入下列命令就可以看到当前所有的环境变量了, 其实它就是很多路径组成的集合
echo $PATH
如果是windows下 则是echo %PATH%
因为当从终端输入字符之后,shell会执行下面三个步骤
- 判断命令是不是函数或者别名(函数和别名拥有执行的最高优先级)
- 判断命令是不是内建命令
- 在环境变量的所有路径下寻找与命令匹配的文件
如果这些过程都没有找到可执行文件,那么就会返回command not found
或者未找到 xx 命令
这样的错误信息了
如果在执行命令的时候,直接指定了完整路径的话,那么shell将不会执行这三个步骤,从而定位到该文件来执行该命令
可执行文件
在linux中,默认的所有的可执行程序都必须有路径才可以执行,其实外部命令也是一个可执行文件,这里为了区分外部命令,定义为带有路径执行的可执行文件,如./a.out 就是一个非常常见的一个可执行文件
a.out 是gcc不加任何参数编译输出的默认的文件
这里我想要表达的是,linux下任何一个文件,给出完整路径后,可以在任何目录下执行,而不依赖于环境变量
比如ls
命令,直接使用ls -al
可以列出当前目录下的所有文件,而它所在的路径一般是/bin/ls
所以在终端下输入
/bin/ls -al
和ls -al
是完全一样的
尾语
当你一个命令不是函数
,别名
,内建命令
,也不是外部命令
,也没有给出完整路径
仍然都找不到命令的话,那么就只有两种原因
- 你的计算机里没有安装这个程序
- 你的命令输入错了
最后让command not found
都见鬼去吧