在这最后一章中,我们收集了一些提示和技巧来帮助您的脚本之旅。首先,我们将涉及一些重要的主题,但在前面的章节中没有直接提到。然后,我们将向您展示一些实用的命令行快捷方式,这将有助于您在做终端工作时提高速度。最后,我们将以本书中讨论的最重要的交互命令的备忘单结束。
本章将介绍以下命令:history
和clear
。
本章将涵盖以下主题:
- 一般提示和技巧
- 命令行快捷方式
- 交互式命令的备忘单
由于本章主要由提示组成,因此没有我们在前面章节中看到的脚本。要真正感受到这些技巧,你应该自己尝试一下。作为最后的告别,你的 Ubuntu 虚拟机可以很好地为你服务这最后一次!
在这一章的第一部分,我们将描述一些我们在书中其他部分无法恰当描述的事情。除了第一个主题,数组,这两个history
和alias
都没有真正在脚本环境中使用,所以我们选择在这里展示它们。但是首先,数组!
如果你来自开发人员背景或涉猎过编程,你将(很可能)遇到术语数组。如果我们需要用一句话来解释数组,它应该是这样的:数组允许我们存储一组相同类型的数据**。为了让这变得不那么抽象,我们将向您展示如何在 Bash 中创建一个字符串数组*:*
reader@ubuntu:~$ array=("This" "is" "an" "array")
reader@ubuntu:~$ echo ${array[0]}
This
reader@ubuntu:~$ echo ${array[1]}
is
reader@ubuntu:~$ echo ${array[2]}
an
reader@ubuntu:~$ echo ${array[3]}
array
在这个字符串数组中,我们放置了四个元素:
- 这
- 存在
- 一;一个
- 排列
如果我们想在数组的第一个位置打印字符串,我们需要用echo ${array[0]}
语法指定我们想要的第零个位置。请记住,正如 IT 中常见的那样,列表中的第一项通常位于第 0 个位置。现在,看看如果我们试图抓住第四个位置,从而抓住第五个值(不存在)会发生什么:
reader@ubuntu:~$ echo ${array[4]}
# <- Nothing is printed here.
reader@ubuntu:~$ echo $?
0
reader@ubuntu:~$ echo ${array[*]}
This is an array
奇怪的是,即使我们要求数组中不存在的位置的值,Bash 也不认为这是一个错误。如果你在一些编程语言中也这样做,比如 Java,你会看到类似于**ArrayIndexOutOfBoundsException**
的错误。在0
退出状态后可以看到,如果我们想打印数组中的所有值,我们使用星号(作为通配符)。
在我们的脚本示例中,为了简单一点,我们在需要创建列表时使用了空格分隔的字符串(作为参考,再次查看第 11 章、条件测试和脚本循环中的脚本**for-simple.sh**
)。根据我们的经验,对于大多数目的来说,这通常更容易操作,并且足够强大。然而,如果您的脚本挑战看起来不是这样的,请记住 Bash 中存在数组这样的东西,也许这些可能对您有用。
Bash 中一个非常强大和酷的命令是history
。简而言之,默认情况下,Bash 将存储您键入的所有命令的历史记录。这些被保存到某个阈值,对于我们的 Ubuntu 18.04 安装,这是内存中的 1000 个命令和磁盘上的 2000 个命令。每次您彻底退出/注销终端时,Bash 都会将命令历史从内存写入磁盘,同时考虑这两个限制。**
**在我们深入(一点)之前,让我们来看看**reader**
用户的个人历史:
reader@ubuntu:~$ history
1013 date
1014 at 11:49 << wall "Hi"
1015 at 11:49 <<< wall "Hi"
1016 echo 'wall "Hi"' | at 11:49
<SNIPPED>
1998 array=("This" "is" "an" "array")
1999 echo ${array[0]}
2000 echo ${array[1]}
2001 echo ${array[2]}
2002 echo ${array[3]}
2003 echo ${array[4]}
2004 echo ${array[*]}
尽管我们的历史很有趣,但在这里全文刊登还不够有趣。通常,如果您在实践中使用这种方法,它也很容易成为信息过载。我们建议您以下列方式使用history
命令:
history | less
history | grep sed
如果你把它接到less
上,你会得到一个很好的寻呼机,你可以从容地浏览并使用中的搜索功能。当您使用**q**
退出时,您将回到您整洁的终端。如果你正在寻找一个特定的命令(比如sed
),你也可以通过grep
命令将history
的输出进行管道化,以制作一个进程过滤器。如果还是太粗糙,可以考虑在grep
后面加| less
,再次使用寻呼机。
历史的配置可以在一些环境变量中找到,这些变量通常在您的**~/.bashrc**
文件中设置:
reader@ubuntu:~$ cat .bashrc
<SNIPPED>
# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
HISTSIZE=1000
HISTFILESIZE=2000
<SNIPPED>
在这里,您可以看到我们已经宣布的两个默认值(如果您愿意,可以对其进行编辑!).对于其他人,man bash
将通知您以下内容:
- 列举控件
- HISTFILE(历史文件)
- HISTTIMEFORMAT
一定要快速阅读。不要低估history
命令的便捷程度;你肯定会发现你自己几乎记得你以前是如何使用命令的,如果你记得足够多,你可以使用history
找出你做了什么,这样你就可以再做一次。
Bash 允许您为命令创建自己的别名。我们在第 14 章、调度和日志中已经看到了这个介绍,但是对于日常任务来说,值得进一步探讨一下。语法非常简单:
alias name=value
在这个语法中,alias
是命令,name
是你在终端上调用alias
的方式,value
是你调用alias
时实际调用的方式。对于交互式工作,这可能如下所示:
reader@ubuntu:~$ alias message='echo "Hello world!"'
reader@ubuntu:~$ message
Hello world!
我们创建了别名message
,它在被调用时实际上为我们做了echo "Hello world!"
。对于那些稍微有点经验的人来说,毫无疑问,你们已经使用“命令”ll
有一段时间了。你可能记得(也可能不记得),这是一个常见的默认alias
。我们可以用-p
标志打印当前设置的别名:
reader@ubuntu:~$ alias -p
<SNIPPED>
alias grep='grep --color=auto'
alias l='ls -CF'
alias la='ls -A'
alias ll='ls -alF'
alias ls='ls --color=auto'
alias message='echo "Hello world!"'
如您所见,默认情况下,我们设置了一些别名,我们刚刚创建的别名也在那里。更有趣的是,我们可以用alias
来覆盖一个命令,比如上面的ls
。我们在书中的例子中一直使用ls
,实际上我们一直在执行ls --color=auto
!grep
也是如此,正如印刷品清楚显示的那样。ll
别名很快允许我们使用ls
通用的、几乎是必不可少的标志。但是,您最好意识到这些别名是特定于分发的。以我的 Arch Linux 主机上的ll
别名为例:
[tammert@caladan ~]$ alias -p
alias ll='ls -lh'
<SNIPPED>
这和我们的 Ubuntu 机器不一样。至少,这回避了一个问题:这些默认别名设置在哪里?如果你还记得我们关于**/etc/profile**
、**/etc/bash.bashrc**
、**~/.profile**
、**~/.bashrc**
(在第 14 章、调度和日志的解释,我们知道这些文件是最有可能的候选文件。根据经验,您可以预期大多数别名都在**~/.bashrc**
文件中:
reader@ubuntu:~$ cat .bashrc
<SNIPPED>
# some more ls aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'
<SNIPPED>
如果您有经常使用的命令,或者您希望“默认”包括的标志,您可以编辑您的**~/.bashrc**
文件,并添加任意数量的alias
命令。.bashrc
文件中的任何命令都会在您登录时运行。如果您想使别名在系统范围内可用,**/etc/profile**
或**/etc/bash.bashrc**
文件将是包含您的alias
命令的更好选择。否则,你将不得不编辑所有用户的个人.bashrc
文件,当前的和未来的(这是没有效率的,所以你甚至不应该考虑这一点)。
除了本章第一部分中的命令的便利性之外,还有另一种类型的省时工具,它不一定需要在 shell 脚本的上下文中讨论,但它仍然是一项巨大的资产,如果我们不与您分享它,我们会感觉很糟糕:命令行快捷方式。
感叹号通常用于给文本一些强调,但在 Bash 下,它们实际上是一个shell
关键词:
reader@ubuntu:~$ type -a !
! is a shell keyword
虽然术语“shell 关键字”并没有给我们一个很好的指示,但是我们可以通过感叹号完成很多事情。一个我们已经看到的:如果我们想否定一个test
,我们可以在检查中提供感叹号。如果您想在您的终端上验证这一点,请使用true
或false
尝试以下操作:
reader@ubuntu:~$ true
reader@ubuntu:~$ echo $?
0
reader@ubuntu:~$ ! true
reader@ubuntu:~$ echo $?
1
如您所见,感叹号反转了退出状态:true 变为 false,false 变为 true。感叹号的另一个很酷的特性是,在命令行中,一个双感叹号将被完整的 previous 命令替换,如下所示:
reader@ubuntu:~$ echo "Hello world!"
Hello world!
reader@ubuntu:~$ !!
echo "Hello world!"
Hello world!
为了确保您清楚自己在重复什么,命令会与命令输出一起打印到 stdout。此外,我们还可以通过使用数字和冒号以及感叹号来选择重复命令的哪个部分。一如既往,0
保留给第一个参数,1
保留给第二个参数,以此类推。这方面的一个很好的例子如下:
reader@ubuntu:/tmp$ touch file
reader@ubuntu:/tmp$ cp file new_file # cp=0, file=1, new_file=2
reader@ubuntu:/tmp$ ls -l !:1 # Substituted as file.
ls -l file
-rw-r--r-- 1 reader reader 0 Dec 22 19:11 file
reader@ubuntu:/tmp$ echo !:1
echo -l
-l
前面的例子说明了我们用**!:1**
替换了前面命令的第二个字。请注意,如果我们对ls -l file
命令重复此操作,第二个单词实际上是ls
命令的-l
标志,因此不要假设只解析完整的命令;这是一个简单的空白分隔索引。
就我们而言,感叹号有一个致命的特点:T0 结构。这是相同类型的替换,从vim
中**$**
的工作原理可以猜到,它替换了前一个命令的最后一个单词。虽然这看起来没什么大不了的,但是看看前一个命令的最后一个单词是您可以重用的:
reader@ubuntu:/tmp$ mkdir newdir
reader@ubuntu:/tmp$ cd !$
cd newdir reader@ubuntu:/tmp/newdir
或者,复制要编辑的文件时:
reader@ubuntu:/tmp$ cp file new_file
reader@ubuntu:/tmp$ vim !$
vim new_file
一旦你开始在实践中使用它,你会发现这个技巧适用于如此多的命令,它会立即开始为你节省时间。在这些例子中,名字很短,但如果我们说的是长路径名,我们要么必须将手从键盘上移开,借助鼠标进行复制/粘贴,要么再次键入所有内容。当一个简单的**!$**
起作用时,你为什么要这么做?
同样,这也可以很快成为救命稻草,有一个非常好的例子说明何时使用**!!**
。看看下面这种情况,大家都遇到过或者迟早会遇到:
reader@ubuntu:~$ cat /etc/shadow
cat: /etc/shadow: Permission denied
reader@ubuntu:~$ sudo !!
sudo cat /etc/shadow
[sudo] password for reader:
root:*:17647:0:99999:7:::
daemon:*:17647:0:99999:7:::
bin:*:17647:0:99999:7:::
<SNIPPED>
当您忘记在命令前添加sudo
(因为它是特权命令或操作特权文件)时,您可以:
- 再次键入整个命令
- 使用鼠标复制并粘贴命令
- 使用向上箭头,后跟 Home 键,并键入
sudo
- 或者简单输入
sudo !!
应该清楚哪一个最短,哪一个最容易,因此有我们的偏好。一定要意识到,这种简单也伴随着责任:如果你试图删除你不应该删除的文件,而你在没有充分考虑的情况下快速使用sudo !!
,你的系统可能会在一瞬间消失。警告仍然存在:当作为**root**
或与sudo
交互时,在运行命令之前要三思。
关于感叹号,我们认为值得描述的最后一件事是与历史的互动。正如您在几页前刚刚了解到的,历史会保存您的命令。使用感叹号,您可以快速运行历史记录中的命令:要么提供命令编号(例如,!100
),要么输入命令的一部分(例如:!ls
)。根据我们的经验,这些功能不如我们稍后将解释的反向搜索使用得多,但是了解这个功能仍然很好。
让我们看看这在实践中的表现:
reader@ubuntu:~$ history | grep 100
1100 date
2033 history | grep 100
reader@ubuntu:~$ !1100
date
Sat Dec 22 19:27:55 UTC 2018
reader@ubuntu:~$ !ls
ls -al
total 152
drwxr-xr-x 7 reader reader 4096 Dec 22 19:20 .
drwxr-xr-x 3 root root 4096 Nov 10 14:35 ..
-rw-rw-r-- 1 reader reader 1530 Nov 17 20:47 bash-function-library.sh
<SNIPPED>
通过提供号码,!1100
再次运行命令date
。你应该意识到,历史一旦达到最大限度,就会发生变化。今天等同于!1100
的命令下周可能会完全不同。在实践中,这被认为是一个有风险的举动,通常最好避免,因为你没有得到确认:你看到正在执行什么,而它正在运行(或者可能,它是在你看到你运行的时候完成的)。只有首先检查历史记录,你才能确定,在这种情况下,你不会节省任何时间,只会使用额外的时间。
有趣的是,基于命令本身重复一个命令,如!ls
所示。这仍然有些风险,尤其是如果与破坏性命令(如rm
)结合使用,但如果您确定最后一个与您的感叹号查询匹配的命令是什么,您应该相对安全(尤其是对于非破坏性命令(如cat
或ls
)。同样,在你开始将这种做法融入你的日常生活之前,一定要坚持阅读,直到我们解释完反向搜索。在这一点上,我们期望/希望这些对你来说更有趣,然后你可以在这里将信息归档为很高兴知道。
我们要讨论的下一类快捷键是键盘快捷键。与前面的命令和 shell 关键字不同,这些只是在命令行上修改东西的组合键。我们讨论的组合都是通过使用 CTRL 键作为修饰符来工作的:您按住 CTRL 并按下另一个键,例如 t 。我们将把它描述为 CTRL+t ,就像我们在本书的其余部分所做的那样。说到**CTRL+t**
,这其实是我们想要解决的第一个捷径!打了一个错别字就可以用CTRL+t
:
reader@ubuntu:~$ head /etc/passdw
# Last two letters are swapped, press CTRL+t to swap them:
reader@ubuntu:~$ head /etc/passwd
因为终端被修改了,所以很难得到这些页面的精确表示。我们在字里行间加入了一条评论,以展示我们做了什么,以及当我们做的时候有什么变化。然而,在你的终端,你只会看到一行。去试试吧。通过按下 CTRL+t ,您可以随时交换最后两个字符。请注意,它也考虑了空白:如果您已经按了空格键,您将会用最后一个字母替换空白,如下所示:
reader@ubuntu:~$ sl
# CTRL+t
reader@ubuntu:~$ s l
如果你开始使用这个快捷方式,你会很快意识到交换两个字母比你最初想象的要常见得多。与 Bash 中的大多数东西一样,这个功能之所以存在,是因为人们使用它,所以如果这种情况发生得太频繁,你不需要对自己感到难过!至少有了这个快捷方式,你将能够快速减少错误。
接下来是**CTRL+l**
快捷方式(小写 L ,其实是一个命令的快捷方式:clear
。clear 的功能几乎和命令的名字一样简单:clear
- 清除终端屏幕(来自man clear
)。这实际上是我们在每个终端会话中广泛使用的一个快捷方式(以及扩展的命令)。当你到达终端模拟器屏幕的底部时,上面有很多杂乱的东西,你可能会注意到这并不像你开始使用的空终端那样好用(我们的个人观点,也许你也有同感)。如果你想清除这个,你可以使用 CTRL+l 快捷键,或者直接输入clear
命令。当您清除终端时,输出并没有消失:您可以一直向上滚动(通常通过鼠标滚轮或SHIFT+向上翻页)来查看清除了什么。但至少你的光标在顶部一个漂亮干净的屏幕上!
还有一个exit
命令的快捷方式,**CTRL+d**
。这不仅在您想要退出 SSH 会话时非常有效,而且在许多其他交互式提示中也有效:一个很好的例子是at
(在现实中,您需要使用 CTRL+d 从at
提示中退出,因为exit
将被解释为运行命令!).如你所知,**CTRL+c**
向一个运行命令发送一个 cancel(技术上是 SIGINT,因为 Linux 下有很多强度的 cancel/kill),所以一定不要混淆 CTRL+d 和 CTRL+c 。
关于导航,有两个基于 CTRL 的快捷方式通常比它们的替代品更容易到达:**CTRL+e**
和**CTRL+a**
。**CTRL+e**
将光标移动到行尾,类似于 end 键完成的操作。正如您所料,**CTRL+a**
的作用正好相反:它可以替代 HOME 键。尤其是对于那些精通触摸打字的人来说,这些快捷键比将右手从主排移开找到 END / HOME 键要快。
在基于图形用户界面的系统中,一个非常常见的事情就是剪切和粘贴文本。你会经常用鼠标选择文本,或者用鼠标右键复制粘贴,或者希望你已经找到了好的旧的**CTRL+c**
和**CTRL+v**
(对于 Windows,命令键对于 macOS)。就像我们之前解释过的,让你想起了前两段,Linux 下的 CTRL+c 绝对不是复制,而是取消。同样的, CTRL+v 也极有可能不会粘贴文字。那么,在 Linux 下,我们如何复制和粘贴呢?
首先,如果您在图形用户界面桌面中使用 SSH 和终端模拟器,您可以使用鼠标右键来实现这一点(或者,如果您真的很喜欢,按鼠标中键通常也默认为粘贴!).您可以从互联网上的某个地方选择文本,例如,复制文本,然后用任一按钮将其粘贴到终端模拟器中。然而,我们总是努力优化我们的流程,一旦你需要抓住鼠标,你就失去了宝贵的时间。对于您已经复制的文本,有(对于大多数终端模拟器!)粘贴的快捷方式:**SHIFT+insert**
。正如您所知,这个粘贴快捷方式并不局限于 Linux 或大多数终端仿真器:它似乎非常通用,也适用于带有图形用户界面的 Windows 和 Linux。就个人而言,为了我们的粘贴需求,我们几乎完全用 SHIFT+insert 代替了 CTRL+v 。
显然,如果我们能以这种方式粘贴,也一定有类似的复制方式。这个很类似:不用SHIFT+插入,可以用**CTRL+insert**
进行复制。同样,这不仅限于 Linux 或终端:它在 Windows 上也能正常工作。对于我们这些使用 Linux 和 Windows 的人来说,将 CTRL+c 和 CTRL+v 替换为 CTRL+insert 和 SHIFT+insert 可以确保无论我们在什么环境下工作,我们总是能够正确地复制和粘贴。个人认为,我们在家里用的是 Linux,在工作中用的是 Windows,这就意味着我们的时间大概是在操作系统之间花掉了 50/50:相信我们,有一直好用的快捷键是非常好的!
现在,上面的方法仍然依赖于鼠标。大多数情况下(根据您的工作,认为超过 95%)会是这种情况,但有时您根本没有鼠标(例如,当直接连接到数据中心服务器的终端时)。对我们来说幸运的是,有三个快捷方式可以在 Bash 中工作,并允许我们直接在命令行上剪切和粘贴:
**CTRL+w**
:剪切光标前的单词**CTRL+u**
:剪切光标前一行的所有内容**CTRL+y**
:粘贴所有被剪切的内容(使用上面两个命令,不是一般的 OS 剪贴板!)
除了可以剪切和粘贴之外, CTRL+w 从命令行中删除一个完整的单词也很棒。请看下面的例子:
reader@ubuntu:~$ sudo cat /etc/passwd # Wrong file, we meant /etc/shadow!
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
<SNIPPED>
# Up-arrow
reader@ubuntu:~$ sudo cat /etc/passwd
# CTRL+w
reader@ubuntu:~$ sudo cat # Ready to type /etc/shadow here.
容易发生的事情是给命令一个不正确的最后参数。如果你想快速修改这个,一个简单的向上箭头后面跟着一个 CTRL+w 将把前面的命令减去最后的参数放回你的终端。现在,你只需要给它正确的参数来再次运行它。或者,您可以:
- 请重新键入整个命令
- 使用鼠标滚动、复制和粘贴
- 向上箭头后面跟着一些退格
根据我们的经验,双击总是比所有其他可能的解决方案都快。只有当最后一个参数是单个字符时,使用向上箭头和退格才会是同样快速的,这有点夸张。
现在,在前面的例子中,我们实际上不仅去掉了最后一个参数,我们实际上去掉了它。当你剪切一个论点时,它给了你再次粘贴的能力。如上所述,这是一个特定于 Bash 的剪贴板,它不绑定到系统剪贴板;虽然您可能认为粘贴总是通过 SHIFT+insert 来完成,但在这种情况下,我们使用 CTRL+y 来粘贴 Bash 特定的剪贴板。展示这一点的最佳示例是使用**CTRL+u**
进行全线切割:
root@ubuntu:~# systemctl restart network-online.target # Did not press ENTER yet.
# Forgot to edit a file before restart, CTRL+u to cut the whole line.
root@ubuntu:~# vim /etc/sysctl.conf # Make the change.
# CTRL+y: paste the cut line again.
root@ubuntu:~# systemctl restart network-online.target # Now we press ENTER.
对我们来说,这是一个典型的场景,我们领先自己一步。我们已经键入了一个需要执行的命令,但是在我们按下回车之前,我们意识到我们忘记了在当前命令成功之前需要做的事情。在这个场景中,我们使用**CTRL+u**
剪切整个命令,继续先决命令,当我们准备好的时候,我们再次用**CTRL+y**
粘贴该行。同样,你可能认为这不会发生在你身上,但你可能会惊讶于你会经常遇到这种精确的模式。
就键盘快捷键而言,我们相信我们已经把最好的留到了最后。在我们目前介绍的所有省时程序中,就我们而言,这是迄今为止最酷的一个:反向搜索。
反向搜索允许您返回历史记录,并在执行的命令中搜索字符串。你可以认为这和history | grep cat
类似,但是互动性更强,速度更快。进入反向搜索提示,使用**CTRL+r**
键:
reader@ubuntu:~$ # CTRL+r
(reverse-i-search)'': # Start typing now.
(reverse-i-search)'cat': cat /var/log/dpkg.log # Press CTRL+r again for next match.
(reverse-i-search)'cat': sudo cat /etc/shadow # When match is found, press ENTER to execute.
reader@ubuntu:~$ sudo cat /etc/shadow
root:*:17647:0:99999:7:::
daemon:*:17647:0:99999:7:::
bin:*:17647:0:99999:7:::
<SNIPPED>
请继续试一试。很难把这些交互式提示写在纸上,所以我们希望上面的评论能很好地说明反向搜索是如何工作的。你可以反向搜索,直到你的历史开始。如果此时再次按下 CTRL+r ,您将看到如下内容:
(failed reverse-i-search)'cat': cat base-crontab.txt
这向您表示没有更多匹配项可供反向搜索查找。此时,或者之前如果觉得花的时间太长,可以随时按 CTRL+c 停止反向搜索。
与!ls
语法相比,反向搜索不会仅从行首开始寻找关键词:
reverse-i-search)'ls': cat grep-then-else.sh
这意味着它既更强大(它只匹配命令中的任何地方)又更复杂(它不仅仅匹配命令)。但是,如果您对此很聪明,并且只想使用命令,那么您可以始终使用适当的空白来确保不会出现上面示例中的情况:
(reverse-i-search)'ls ': ls -al /tmp/new # Note the whitespace after ls.
虽然我们很想更多地谈论反向搜索,但你要正确学习它的唯一真正方法是开始使用它。请放心,如果您精通它的使用(并且还知道何时停止搜索,只需键入您正在寻找的命令),您一定会用您高效的终端工作打动您的同行!
我们将以一个用于交互式命令的简单备忘单来结束这本书。精通 Bash 是一个练习的问题。然而,这些年来,我们发现自己偶然发现了新的方法来使用我们不知道的命令或标志,这让我们的生活变得容易得多。甚至在写这本书的过程中,我们遇到了以前不知道的事情,这些事情非常有帮助。在编写命令和构造的过程中,您会更仔细地查看手动页面和资源,而不是在日常业务中简单地使用它们。
请利用这些备忘单,因为它们不仅包括基本语法,还包括我们认为非常值得了解的标志和提示(我们希望在职业生涯的早期找到它们)!
这些备忘单不包括诸如查找/定位、重定向、测试和循环之类的内容:这些(希望)已经在它们各自的章节中进行了充分的描述。
这些命令用于导航。
| 描述 | 更改 shell 工作目录。 | | 语法 | CD [目录] | | 实际用途 |
cd
: Navigate to the home directory (specified in home).cd -
: Navigate back to the previous directory (saved in OLDPWD).
|
| 描述 | 列出目录内容。 | | 语法 | ls [OPTION]...[文件]... | | 实际用途 |
ls -a
: Don't ignore items that start with a dot (). And ...).ls -l
: Use long list format.ls -h
: use-l
and/or-s
to print a human-readable size (for example, 1K 234M 2G).ls -R
: Recursively list subdirectories.ls -S
: Sort by file size, with the highest priority.ls -t
: Sort by modification time, with the latest priority.ls -ltu
: sort basis, display access time.ls -Z
: Print any security context of each file.
|
| 描述 | 打印当前/工作目录的名称。 | | 语法 | pwd[选项]-我...。 |
这些命令用于文件操作。
| 描述 | 连接文件并在标准输出上打印。 | | 语法 | 卡特彼勒[选项]...[文件]... | | 实际用途 |
cat
orcat -
: If there is no file, or if the file is-,read the standard input.cat -n
: Number all output lines.
|
| 描述 | 使用寻呼机一次在一个屏幕上浏览文本。 | | 语法 | 减去[选项]...[文件]... | | 实际用途 |
less -S
: Cut the long queue. The line does not wrap around, but it can be seen with the left and right arrow keys.less -N
: Displays the line number.
|
| 描述 | 更改文件时间戳和/或创建空文件。 | | 语法 | 触摸[选项]...文件... | | 实际用途 |
touch <non-existent-file>
: Create an empty file.
|
| 描述 | 制作目录。 | | 语法 | mkdir [OPTION]...目录... | | 实际用途 |
mkdir -m750 <dirname>
: Create a directory with specified octal permissions.mkdir -Z
: Set the SELinux security context of each created directory to the default type.
|
| 描述 | 复制文件和目录。 | | 语法 | CP[选项]...来源...目录 | | 实际用途 |
cp -a
: Archive mode, which retains all permissions, links, attributes, etc.cp -i
: Prompt before overwriting (-n
option before overwriting).cp -r
andcp -R
: Recursively copy directories.cp -u
: Copy only when the source file is newer than the target file or the target file is missing.
|
| 描述 | 删除文件或目录。 | | 语法 | rm [OPTION]...[文件]... | | 实际用途 |
rm -f
: Ignore nonexistent files and parameters, and never prompt.rm -i
: Prompt before each removal.rm -I
(capital I): prompt once before deleting more than three files, or once when recursively deleting; It is less invasive than -i and can prevent most errors at the same time.rm -r
rm -R
: Recursively delete the directory and its contents.
|
| 描述 | 移动(重命名)文件。 | | 语法 | mv[选项]...来源...目录 | | 实际用途 |
mv -f
: Do not prompt before overwriting.mv -n
: Do not overwrite existing files.mv -u
: Move only when the source file is newer than the target file or the target file is missing.
|
| 描述 | 在文件之间建立链接。默认为硬链接。 | | 语法 | [选项]...[-T]目标链接名 | | 实际用途 |
ln -s
: Do symbolic link instead of hard link.ln -i
: Prompt whether to delete the destination.
|
| 描述 | 输出文件的第一部分。 | | 语法 | 标题[选项]...[文件]... | | 实际用途 |
head
: Print the first 10 lines of each FILE to standard output.head -n20
orhead -20
: print the first NUM line instead of the first 10 lines.head -c20
: print the first NUM bytes of each file.head -q
: Do not print the title giving the file name.
|
tail
命令的选项与head
相同,但从文件的结尾而不是开头来看。
| 描述 | 输出文件的最后一部分。 | | 语法 | 尾部[选项]...[文件]... |
这些命令用于权限和所有权操作。
| 描述 | 更改文件模式位。可以指定为 rwx 或八进制模式。 | | 语法 | chmod [OPTION]...八进制模式文件... | | 实际用途 |
chmod -c
: I like to be long-winded, but I will report any changes.chmod -R
: Recursively change files and directories.chmod --reference=RFILE
: Copy mode from reference file.
|
| 描述 | 设置文件模式创建掩码。由于这是一个遮罩,它是正常八进制模式的反向。 | | 语法 | 八进制掩码 |
| 描述 | 更改文件所有者和组。仅具有根权限的可执行文件。 | | 语法 | chown [OPTION]...[所有者][:[组]]文件... | | 实际用途 |
chown user: <file>
: Change ownership to users and their default groups.chown -c
: I like to be verbose, but I will report it only if I make changes.chown --reference=RFILE
: Copy the ownership from the reference file.chown -R
: Recursively operate files and directories.
|
| 描述 | 更改组所有权。 | | 语法 | chgrp [OPTION]...分组文件... | | 实际用途 |
chgrp -c
: I like to be long-winded, but I will report any changes.chgrp --reference=RFILE
: Copy the group ownership from the reference file.chgrp -R
: Recursively operate files and directories.
|
| 描述 | 以另一个用户的身份执行命令。 | | 语法 | sudo[选项]-我...。 | | 实际用途 |
sudo -i
: Become the root user.sudo -l
: List the commands that call user permission (and prohibition).sudo -u <user> <command>
: Run < command > as the designated < user >.sudo -u <user> -i
: Log in with the specified < user >.
|
| 描述 | 更改用户标识或成为超级用户。 | | 语法 | su[选项][用户名] | | 实际用途 |
sudo su -
: Switch to root user. If you need sudo, you can choose to use your own password.su - <user>
: Switch to < User >. Password is required for < user >.
|
| 描述 | 创建新用户或更新默认的新用户信息。 | | 语法 | user add[选项]登录 | | 实际用途 |
useradd -m
: If it does not exist, create the user's home directory.useradd -s <shell>
: The name of the user login shell.useradd -u <uid>
: numerical value of user ID.useradd -g <group>
: the group name or number of the user's initial login group.
|
| 描述 | 创建新组。 | | 语法 | 组添加[选项]组 | | 实际用途 |
groupadd -g <gid>
: the numerical value of this group ID.groupadd -r
: Create a system group. The GID of these websites is (usually) lower than that of users.
|
| 描述 | 修改用户帐户。 | | 语法 | 用户模式[选项]登录 | | 实际用途 |
usermod -g <group> <user>
: Change the main group > of < users to < group >.usermod -aG <group> <user>
: Add < user > to < group >. For users, this will be a supplementary group.usermod -s <shell> <user>
: Set the login shell for < user >.usermod -md <homedir> <user>
: Move the home directory of < user > to < home directory >.
|
我们从一般提示和技巧开始这最后一章。本章的这一部分涉及数组、history
命令,以及使用alias
为您最喜欢的命令及其标志设置别名的能力。
我们继续使用键盘快捷键。我们从讨论感叹号及其在 Bash 中的用途开始这一部分:它用于否定退出代码,替换以前命令的一部分,甚至通过匹配行号或行内容来运行历史命令。之后,我们展示了 Bash 的几个有趣的键盘快捷键如何让我们在常见的操作和使用模式上节省一些时间(比如错别字和被遗忘的中间命令)。我们最后保存了最好的键盘快捷键:反向搜索。这些允许您交互式地浏览您的个人历史,以找到正确的命令来再次执行。
我们在这一章和这本书的结尾用了一个小抄来记录我们在这本书里介绍的大多数命令。该备忘单包含所有命令的基本语法,以及我们最喜欢的命令标志和组合。
本章介绍了以下命令:history
和clear
。
如果你已经做到了这一步:谢谢你阅读我们的书。我们希望你喜欢阅读它,就像我们喜欢创作它一样。继续编写脚本和学习:熟能生巧!***