Shell命令
1. Shell命令基本格式
Shell 命令的基本格式如下:
command [选项] [参数]
[]
表示可选的,也就是可有可无。有些命令不写选项和参数也能执行,有些命令在必要的时候可以附带选项和参数。
比如:ls 是常用的一个命令,它属于目录操作命令,用来列出当前目录下的文件和文件夹。ls 可以附带选项,也可以不带,不带选项的写法为:
[cuining@localhost ~]$ cd demo
[cuining@localhost demo]$ ls
demo.txt
先执行cd demo
命令进入demo目录,这是我在自己的主目录下创建的文件夹,里面创建了一个文本文件demo.txt。接着执行 ls 命令,列出了 demo 目录下的所有文件,并且进行了格式对齐。
-
使用选项
ls 命令之后不加选项和参数也能执行,不过只能执行最基本的功能,即显示当前目录下的文件名。那么加入一个选项,会出现什么结果?如果加一个
-l
选项,则可以看到显示的内容明显增多了。-l
是长格式(long list)的意思,也就是显示文件的详细信息。[cuining@localhost demo]$ ls -l 总用量 4 -rw-rw-r--. 1 cuining cuining 17 4月 8 17:56 demo.txt
可以看到,选项的作用是调整命令功能。如果没有选项,那么命令只能执行最基本的功能;而一旦有选项,则能执行更多功能,或者显示更加丰富的数据。
短格式选项和长格式选项
Linux 的选项又分为短格式选项和长格式选项。
短格式选项是长格式选项的简写,用一个减号
-
和一个字母表示,例如ls -l
。长格式选项是完整的英文单词,用两个减号--
和一个单词表示,例如ls --all
。一般情况下,短格式选项是长格式选项的缩写,也就是一个短格式选项会有对应的长格式选项。当然也有例外,比如 ls 命令的短格式选项-l
就没有对应的长格式选项,所以具体的命令选项还需要通过帮助手册来查询。 -
使用参数
参数是命令的操作对象,一般情况下,文件、目录、用户和进程等都可以作为参数被命令操作。但是为什么一开始 ls 命令可以省略参数?那是因为有默认参数。命令一般都需要加入参数,用于指定命令操作的对象是谁。如果可以省略参数,则一般都有默认参数。例如 ls 命令后面如果没有指定参数的话,默认参数是当前所在位置,所以会显示当前目录下的文件名。
Shell 命令可以同时附带选项和参数,例如:
[cuining@localhost ~]$ echo "hello" hello [cuining@localhost ~]$ echo -n "hello" hello[cuining@localhost ~]$
-n
是 echo 命令的选项,"hello"
是 echo 命令的参数,它们被同时用于 echo 命令。echo 命令用来输出一个字符串,默认输出完成后会换行;给它增加-n
选项,就不会换行了。 -
选项附带的参数
有些命令的选项后面也可以附带参数,这些参数用来补全选项,或者调整选项的功能细节。例如,read 命令用来读取用户输入的数据,并把读取到的数据赋值给一个变量,它通常的用法为:
read str
str 为变量名。如果我们只是想读取固定长度的字符串,那么可以给 read 命令增加
-n
选项。比如读取一个字符作为性别的标志,那么可以这样写:read -n 1 sex
1
是-n
选项的参数,sex
是 read 命令的参数。-n
选项表示读取固定长度的字符串,那么它后面必然要跟一个数字用来指明长度,否则选项是不完整的。
2. Shell命令的本质
Shell 命令分为两种:
- Shell 自带的命令称为内置命令,它在 Shell 内部可以通过函数来实现,当 Shell 启动后,这些命令所对应的代码(函数体代码)也被加载到内存中,所以使用内置命令是非常快速的。
- 更多的命令是外部的应用程序,一个命令就对应一个应用程序。运行外部命令要开启一个新的进程,所以效率上比内置命令差很多。
用户输入一个命令后,Shell 先检测该命令是不是内置命令,如果是就执行,如果不是就检测有没有对应的外部程序:有的话就转而执行外部程序,执行结束后再回到 Shell;没有的话就报错,告诉用户该命令不存在。
-
内置命令
内置命令很少,因为过多的内置命令会导致 Shell 程序本身体积膨胀,运行 Shell 程序后就会占用更多的内存。Shell 是一个常驻内存的程序,占用过多内存会影响其它的程序。只有那些最常用的命令才有理由成为内置命令,比如 cd、kill、echo 等;
-
外部命令
外部命令可能是令人比较疑惑的,一个外部的应用程序究竟是如何变成一个 Shell 命令的呢?一般而言,应用程序就是一个文件,只不过这个文件是可以执行的。既然是文件,那么它就有一个名字,并且存放在文件系统中。用户在 Shell 中输入一个外部命令后,只是将可执行文件的名字告诉了 Shell,但是并没有告诉 Shell 去哪里寻找这个文件。难道 Shell 要遍历整个文件系统,查看每个目录吗?这显然是不能实现的。为了解决这个问题,Shell 在启动文件中增加了一个叫做 PATH 的环境变量,该变量就保存了 Shell 对外部命令的查找路径,如果在这些路径下找不到同名的文件,Shell 也不会再去其它路径下查找了,它就直接报错。具体什么是启动文件不需要太关心,只需要知道 PATH 变量保存了检索路径即可。可以通过 echo 命令输出 PATH 变量的值,看看它保存了哪些检索路径:
[cuining@localhost ~]$ echo $PATH /usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/home/cuining/.local/bin:/home/cuining/bin
不同的路径之间以
:
分隔。Shell 只会在这几个固定的路径中查找外部命令。
总而言之,Shell 内置命令的本质是一个自带的函数,执行内置命令就是调用这个自带的函数。因为函数代码在 Shell 启动时已经被加载到内存了,所以内置命令的执行速度很快。而Shell 外部命令的本质是一个应用程序,执行外部命令就是启动一个新的应用程序。因为要创建新的进程并加载应用程序的代码,所以外部命令的执行速度很慢。
3. Shell命令提示符
启动 Linux 桌面环境自带的终端模拟包,或者从 Linux 控制台登录后,便可以看到 shell 命令提示符。看见命令提示符就意味着可以输入命令了。命令提示符不是命令的一部分,它只是起到一个提示作用。不同的 Linux 发行版使用的提示符格式大同小异,例如在 CentOS 中,默认的提示符类似下面这样:
[cuining@localhost ~]$
各个部分的含义如下:
[]
是提示符的分隔符号,没有特殊含义。cuining
表示当前登录的用户,我现在使用的是 cuining 用户登录。@
是分隔符号,没有特殊含义。localhost
表示当前系统的简写主机名(完整主机名是 localhost.localdomain)。~
代表用户当前所在的目录为主目录(home 目录)。如果用户当前位于主目录下的 bin 目录中,那么这里显示的就是bin
。$
是命令提示符。Linux 用这个符号标识登录的用户权限等级:如果是超级用户(root 用户),提示符就是#
;如果是普通用户,提示符就是$
。
总结起来,Linux Shell 默认的命令提示符的格式为:
[username@host directory]$
或者
[username@host directory]#
Linux 系统是纯字符界面,用户登录后,要有一个初始登录的位置,这个初始登录位置就称为用户的主目录(home 目录)。超级用户的主目录为/root/
,普通用户的主目录为/home/用户名/
。用户在自己的主目录中拥有完整权限。
-
Shell修改命令提示符
shell通过
PS1
和PS2
这两个环境变量来控制提示符的格式,修改PS1
和PS2
的值就能修改命令提示符的格式。- PS1 控制最外层的命令提示符格式。
- PS2 控制第二层的命令提示符格式。
在修改 PS1 和 PS2 之前,先用 echo 命令输出它们的值,看看默认情况下是什么样子的:
[cuining@localhost ~]$ echo $PS1 [\u@\h \W]\$ [cuining@localhost ~]$ echo $PS2 >
Linux使用以
\
为前导的特殊字符来表示命令提示符中包含的要素,这使得 PS1 和 PS2 的格式看起来可能有点奇怪。下表展示了可以在 PS1 和 PS2 中使用的特殊字符。字符 描述 \a 铃声字符 \d 格式为“日 月 年”的日期 \e ASCII 转义字符 \h 本地主机名 \H 完全合格的限定域主机名 \j shell 当前管理的作业数 \1 shell 终端设备名的基本名称 \n ASCII 换行字符 \r ASCII 回车 \s shell 的名称 \t 格式为“小时:分钟:秒”的24小时制的当前时间 \T 格式为“小时:分钟:秒”的12小时制的当前时间 @ 格式为 am/pm 的12小时制的当前时间 \u 当前用户的用户名 \v bash shell 的版本 \V bash shell 的发布级别 \w 当前工作目录 \W 当前工作目录的基本名称 \! 该命令的 bash shell 历史数 \# 该命令的命令数量 \$ 如果是普通用户,则为美元符号 $
;如果超级用户(root 用户),则为井号#
。\nnn 对应于八进制值 nnn 的字符 \\ 斜杠 \[ 控制码序列的开头 \] 控制码序列的结尾 注意,所有的特殊字符均以反斜杠
\
开头,目的是与普通字符区分开来。可以在命令提示符中使用以上任何特殊字符的组合。【实例】通过修改 PS1 变量的值来修改命令提示符的格式:
[cuining@localhost ~]$ PS1="[\t][\u]\$ " [12:51:43][mozhiyan]$
修改后可以显示当前的时间和用户名,遗憾的是,通过这种方式修改的命令提示符只在当前的 Shell 会话期间有效,再次启动 Shell 后将重新使用默认的命令提示符。如果希望持久性地修改 PS1,让它对任何 Shell 会话都有效,那么就得把 PS1 变量的修改写入到 Shell 启动文件中,具体操作关注后续文章。
欢迎关注在下的微信公众号