🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## 第 14 章 命令系统 **目录** [](ch14.html#id3062639) [Shell、Console、Terminal](ch14s02.html) [rxvt-unicode](ch14s03.html) [帮助系统](ch14s04.html) [bash](ch14s05.html) [中止正在运行的程序](ch14s05.html#id3063134) [Ctrl+s](ch14s05.html#id3063154) [键绑定](ch14s05.html#id3063175) [自定义键绑定](ch14s05.html#id3063672) [](ch14s06.html) [通配符](ch14s06.html#glob) [任务管理](ch14s06.html#id3063827) [管道、重定向](ch14s06.html#id3063966) [脱字符](ch14s06.html#id3064064) [设定您的默认 Shell](ch14s07.html) [设定命令的搜索路径](ch14s08.html) ## Shell、Console、Terminal 在前面的章节中,我们曾提到,电视机的遥控器,也是一种人机交互的界面,算是一种 Shell。 但是这个概念并不准确,遥控器只是向 Shell 发送指令的工具,Shell 接收到遥控器发出指令后,将指令转换为系统命令,由系统来执行。 例如我们按的遥控器上的 数字键1 ,遥控器将 切换为1频道 的指令发送到 Shell,Shell 将指令转换为系统可以识别的 频道1 ,系统执行它,您就可以观看 1频道 的电视节目了。 通常每台电视机只有一种 Shell,比如有的电视机系统具有“画中画”的功能,那么 Shell 中便有相应的功能定义,您可以通过遥控器上的“画中画 ”功能键来开启它。假设您的电视机没有此功能,Shell 中也就没有相应的功能定义。拥有一个带“画中画”功能控制键的遥控器,即便信号兼容,您还是不能够使用这一功能 不用遥控器也可以控制电视机,假设您的遥控器丢了,您还可以走到电视机前,使用机身上的控制面板来控制它(相当于使用 Linux 的控制台)。但是您一定不喜欢这种方式,除非您想锻炼身体 在 Linux 系统中,由于图形界面和控制台的分辨率通常不一致,所以切换时要有一个延时。对于我们中文用户来讲,控制台下中文的显示也比较麻烦。而且控制台显示内容通常不如终端显示的全面。 所以我们推荐您使用终端来执行命令,它使用起来感觉很像遥控器 ## rxvt-unicode 通常情况下,您买一台电视机,只能获得一个遥控器。虽然它为您的电视机量身定作,能够最大限度发挥电视机的能力,但您却不一定喜欢它。说不定这个遥控器体形太大,持握不方便;或者它体形太小,容易失踪;又或者它的按键要么太硬,要么太软;它的键盘要么太大,要么太小…… 您一般也可以容忍,毕竟遥控器使用频率并不算高 如果您的终端有些地方不讨您喜欢,比如说响应太慢,或者不能正常显示中文……那就难以忍受了,您应该换一个其它的试试。 您所接触的第一个终端极有可能是 Gnome-Termianl,它是系统默认使用的终端,显示中文不错,不过响应比较慢。。。 我们推荐您使用 urxvt(mlterm 也是不错的选择) 您可以使用 **sudo apt-get install rxvt-unicode** 命令来安装它。 `urxvt` 启动它 (urxvt 不支持控制台,您得在图形界面下启动它。使用终端,或者按下 Alt+F2,建议您在启动栏里新建一个启动图标) rxvt-unicode 还支持“服务器/客户端”的运行模式: * `urxvtd` 启动一个守护进程 daemon(支持控制台) * `urxvtc` 启动客户端 client。多个客户端可以同时连接到一个 urxvtd,以达到节省系统资源的目的。 或许您对 rxvt 的默认设置不满意,您可以修改用户配置文件 `~/.Xresources` 来设定它。修改全局配置文件 `/etc/X11/Xresources/Xresources` ,则对所有用户生效,只有 root 才可以修改此文件。 这里有一些简单的选项:(以 ! 起始的行是注释,您可以直接拷贝此文件的内容) **例 14.1. urxvt 配置 `~/.Xresources`** ``` !!============================================================================= !! RXVT-unicode setting !!============================================================================= !设置字体分辨率 Xft.dpi:96 !设置字体 URxvt.font:-misc-fixed-medium-r-normal--14-*-*-*-*-*-iso10646-1,xft:WenQuanYi Bitmap Song:size=10 !颜色 Rxvt.background:black Rxvt.foreground:white Rxvt.colorBD:yellow Rxvt.colorUL:green !滚动条 Rxvt.scrollBar:True Rxvt.scrollBar_right:True Rxvt.scrollBar_floating: False Rxvt.scrollstyle:plain !屏幕缓冲 Rxvt.saveLines:10000 Rxvt.color12:DodgerBlue Rxvt.menu:/etc/X11/rxvt.menu Rxvt.preeditType:Root !输入法设置 !inputMethod:xim ``` ## 帮助系统 您可以使用命令 man 或者 info 来阅读 Linux 命令的在线文档。命令的格式非常简单: ``` man xxx ``` > 提示:在使用 man 浏览器的时候,一些快捷键您可能会用到: | | | | --- | --- | | Ctrl+f(orward) | 向下翻一页 | Ctrl+d(own) | 向下翻半页 | | Ctrl+b(ackward) | 向上翻一页 | Ctrl+u(p) | 向上翻半页 | | / | 查找 | q(uit) | 退出 | 以上为 VI风格 的键绑定。您也可以使用 Emacs风格 的[键绑定](ch14s05.html#keybind "表 14.1. Emacs风格 键绑定") ## bash 好了,现在我们换了一个遥控器,感觉顺手多了。现在来操练一下,下载一首 mp3: 我们使用 wget 这个程序,它非常可靠,完全值得您信赖。 首先找到一个可以下载的地址,复制链接,在终端窗口内点击鼠标中键,把它粘贴进去。 现在终端中大概是这种情形: ``` http://linuxtoy.org/xxx.mp3 ``` 按下 `Ctrl+a` 组合键,我们发现光标移动到了行首。输入 `wget` 和 `空格` ``` wget http://linuxtoy.org/xxx.mp3 ``` 回车后,终端中出现一些信息,不一会儿工夫,mp3 便下载完成。 使用 `Ctrl+a` 组合键,我们就不需要使用方向键来移动光标,方向键每次只能移动一个字符,没有效率 您还可以使用 `Ctrl+f` 向前移动光标, `Ctrl+b` 向后移动光标, `Ctrl+e` 将光标移动到行末……([键绑定](ch14s05.html#keybind "表 14.1. Emacs风格 键绑定")) > 注意:Linux 的图形界面中,鼠标中键通常执行“粘贴”的操作,如果您的鼠标没有中键,您可以左右键同时按下。 ### 中止正在运行的程序 如果一个命令持续时间很长,以致于不能够进行其它操作,可以使用 `Ctrl+c` 来强行中止它。 ### Ctrl+s 有时您会不小心按下 `Ctrl+s` 这个组合键,Shell 便被冻结。尝试使用 `Ctrl+q` 组合键,看能否恢复正常。 ### 键绑定 等等,有必要记这么多快捷键么?都这么复杂! 我们强烈建议您记住,以大幅度的提高操作效率。而且这是 readline 控件的键绑定,在任何使用 readline 控件的程序中,您都可以使用它们。例如 bash、lftp、gdb 等程序;同时,Linux 下倍受追捧的 Emacs 编辑器,也是这种风格的键绑定(其实是 readline 使用了 Emacs风格 的键绑定才对),甚至 FireFox 中,也可以使用类似风格的快捷键!(Linux 下主要有两种风格的键绑定,一种是 Emacs风格,另一种是 Vi风格,我们会在 [第 24 章 _Vim 编辑器_](ch24.html "第 24 章 Vim 编辑器") 中介绍) 现在列举一些 ReadLine 的键绑定,您可以自行尝试。(运行 `man readline` 命令,来查看 ReadLine 手册) 先来了解一些约定: * \C-a 表示 `Ctrl+a` * \M-a 表示 `Meta+a` Meta键 在 PC 中通常为 ALT键 **表 14.1. Emacs风格 键绑定** | | | | --- | --- | | | 向前 | 向后 | | 移动 | | 行 | \C-a | Ahead | \C-e | End | | 字符 | \C-f | Forward | \C-b | Backward | | 单词 | \M-f | \M-b | | 命令 | \C-n | Next | \C-p | Previous | | 删除 | | 行 | \C-u | \C-k | | 字符 | \C-h | \C-d | | 单词 | \C-w | \M-d | | 搜索 | | 搜索 | \C-r (连续使用 C-r 可以查找下一个) | | 浏览搜索结果 | \M-n | \M-p | | 其它 | | 粘贴 | C-y | | 撤销 | C-- | | 清空屏幕 | C-l | _自动补全_ | | | | --- | --- | | Tab | 使用频率最高的功能! | | \C-o | 遍历补全 | (未定义) | | \M-? | 列出所有可能选项,相当于按两次 Tab键 | Alt+Shift+/ | | \M-# | 注释掉当前命令,用于将当前命令暂存于历史纪录列表 | Alt+Shift+3 | | \M-! | 补全命令,通常用来补全子命令,例如 ``sudo`` 的子命令 | Alt+Shift+1 | | \M-~ | 补全用户名 | Alt+Shift+` | | \M-@ | 补全主机名 | Alt+Shift+2 | | \M-$ | 补全变量 | Alt+Shift+4 | | \M-_ | 补全历史纪录中的纪录 | Alt+Shift+- | | \M-* | 将所有可能选项放到命令行中 | Alt+Shift+8 | ### 自定义键绑定 通过修改 `/etc/inputrc` 文件,可以更改键绑定。建议您使用默认的键绑定,以避免不必要的烦恼。当然了,Emacs风格 的键绑定是通用的,随时都有可能用到。 在文件中添加该行,可以将 ReadLine 的键绑定设为 VI风格。(Bash、Lftp 等使用 ReadLine 的软件同时生效) ``` set editing-mode vi ``` 找到这一行: ``` $if mode=emacs ``` 在它的下面添加如下内容 ``` "\C-o": menu-complete ###这两行不是必须的,视情况而定### "\C-p": non-incremental-reverse-search-history "\C-n": non-incremental-forward-search-history ``` 重新登录 Shell,您就可以使用 `\C-o` (Ctrl+o)来遍历补全。假如您的文件名为中文,或者出现乱码时,您可以使用 `\M-*` 将所有文件名放入命令行,再删除多余的,这真是麻烦极了!简单一点的方法是使用 `\C-o` 遍历补全,将所有可能的选项轮流放入命令行。 > 提示:使用 Vim编辑器, **vi /etc/inputrc** ,在插入模式下使用 `Ctrl+v` 组合键。按下 `Ctrl+o` ,这时编辑区新增一个 ^O 字符,等价于 `\C-o` ### 通配符 使用 _?_ 代表任意单个字符。例如 ???lo ,表示 lo 前有三个字符,它可以匹配 Hello 使用 _*_ 代表随意几个任意字符。例如 *.iso ,代表所有 iso 格式的文件。 您可以将遍历补全和通配符结合使用,以提高效率。例如: ``` cd */ 则遍历补全只补全文件夹 chmview *.chm 则遍历补全只补全 chm 文件 ``` ### 任务管理 & 在命令的末尾加上一个 & 符号,表示背景任务,例如: ``` wget http://www.download.net/xxx/mp3 & ``` ; 使用 ; 将多个命令连结起来,则表示任务按顺序执行 && 使用 && 将多个命令连结起来,则表示只有前面的命令执行成功,后面的命令才能得以执行 `` `(命令)` ,如果一个命令中包含以 `` (Esc键 下方的按键)括起来的子命令,那么子命令将被优先执行,执行结果被代入上一级命令继续执行,例如创建一个以当前时间命名的文件: ``` touch `date +%m.%d_%H:%M:%S` ``` touch 命令能够创建一个文件,它的操作对象,为 date +%m%d%H%M%S 命令的输出 06.06_06:06:60 这样,我们创建了一个名为 06.06_06:06:60 的文件(六月六日六时六分刚过六十秒-_-!) Ctrl+z 将当前 Shell 中的任务挂起,这个时候任务的状态为 ``` [1]+ Stopped xxx ``` bg 将挂起的任务背景运行。这时它的状态为 ``` [1]+ xxx & ``` fg 将背景任务调到前台执行 jobs 查看背景任务,方括号中的数字为命令的任务编号 如果后台运行多个任务,您可以在 bg 或者 fg 后跟任务编号,作为操作对象,例如: ``` bg 2 ``` ### 管道、重定向 > 重定向符号,它的作用是将命令的输出重定向到一个文件中。比如我们想把命令 **ls** 的结果保存为 `FileList` 文件,作一个清单,我们可以使用重定向符号来完成它: ``` ls -l > FileList ``` >> 作用与 > 基本相同,不同点在于, >> 以追加的方式,将命令的输出写入文件的末尾。 < 是从文件到命令的重定向,将文件的内容作为命令的输入。 | 为管道符号,它的作用是将前一个命令的输出,作为下一个命令的输入。假设一个目录下的文件太多,使用 ls 命令不能够在屏幕中完全显示,这个时候您可以将 ls 命令的输出,通过管道符号,作为浏览器 less 的输入。就可以使用浏览器的功能翻页、查找: ``` ls -al | less ``` > 提示:less 浏览器的键绑定几乎与 man 相同,请参阅[“帮助系统”一节](ch14s04.html "帮助系统") ### 脱字符 Shell 中的一些功能是通过特殊符号作为控制字符来实现的,上面已经介绍了很多了。这产生一个问题,如果一个文件名中,刚好包含了这些字符,比如 ; ,就很难对它进行操作。使用 less 浏览这个文件 ``` less ;xxx ``` less 会很快返回一个错误信息,因为并没有一个文件名作为操作对象。接着,Shell 会报告,系统中没有 xxx 这个命令。 这是因为 Shell 将文件名中的 ; 解析为按顺序执行命令。 或者您的文件名以空白起始,而在 Shell 中,无论多少个空格,都将被解析为一个分隔符。您甚至不能使用命令重命名此文件。 这个时候就要用到脱字符 _\_ 了,它能够将一个具有特殊涵义的字符转换普通字符。上面的两个任务,可以在文件名中每个特殊字符前加一个 \ ,像这样 ``` less \;xxx less \ \xxx less \;\ \&\xxx ``` > 提示:也可以使用 " 将文件名括起来,例如 **less "; &xxx"** ,在很多情况下,这样甚至更方便。 脱字符在 Shell 中也可以作为换行符,在一个命令的末尾添加一个 \ ,然后回车,在下一行继续输入命令剩余的部分,将一个命令拆分为多行且不影响它的执行(如果执行一个很长的命令,请将它拆分为多行以便于阅读) 事实上换行符也符合脱字符的定义。回车键有两个涵义,一个是 执行 (Enter),另一个 换行 (折线箭头)。在 Shell 中它作为控制字符 执行 ,使用脱字符后,它便代表排版字符 换行 了。 ## 设定您的默认 Shell 如果能够拥有 root权限,可以直接修改 `/etc/passwd` 文件。找到您 用户ID 起始的行 ``` user:x:1000:112:user,,,:/home/user:/bin/bash ``` > [![1](https://box.kancloud.cn/2015-10-12_561bcb76795ae.png)](ch14s07.html#command11) 用户登录名 > [![2](https://box.kancloud.cn/2015-10-12_561bcb768596e.png)](ch14s07.html#command12) 用户口令(通常转储在`/etc/shadow`文件中) > [![3](https://box.kancloud.cn/2015-10-12_561bcb94ee26f.png)](ch14s07.html#command13) 用户UID > [![4](https://box.kancloud.cn/2015-10-12_561bcb9508b82.png)](ch14s07.html#command14) 用户GID > [![5](https://box.kancloud.cn/2015-10-12_561bcb95133e7.png)](ch14s07.html#command15) 用户信息 > [![6](https://box.kancloud.cn/2016-01-06_568cdb4f32753.png)](ch14s07.html#command16) 用户`$HOME`目录位置 > [![7](https://box.kancloud.cn/2016-01-06_568cdb4f41fcc.png)](ch14s07.html#command17) 最后一个字段为登录后的默认 Shell, `/bin/bash` 是程序 bash 的主程序路径。 Zsh 主程序的路径通常为 `/bin/zsh` `/etc/shells` 中列出系统中所有可用 Shell( `/bin/false` 代表禁用 Shell) 也可以使用如下命令更改您的默认 Shell ``` chsh -s /bin/zsh (需要输入您的密码) ``` ## 设定命令的搜索路径 使用 **echo $PATH** ,可以显示 `$PATH` 变量,输出如下: ``` /usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /usr/bin/X11 /usr/games /usr/X11R6/bin ``` 它是一个环境变量,代表执行命令时,Shell 的搜索路径。 执行一个命令时,Shell 会到 `$PATH` 变量定义的路径去搜索,并运行与命令同名的可执行文件。如果程序、脚本等可执行文件并不在上面的路径中,就必须使用绝对路径或者相对路径定位可执行文件。 例如: ``` /usr/local/mplayer -menu xxx.rmvb cd /usr/local/ && ./mplayer -menu xxx.rmvb ``` 可以修改 `/etc/environment` 文件来设定您的命令搜索路径,找到 PATH 起始的行 ``` PATH="$PATH:/user/" ``` 在双引号中添加您的自定义路径,并以 _:_ 分隔。