如何使用在Linux VPS的Bash历史命令与扩展

介绍

在服务器环境中工作时,您将花费大量的时间在命令行上。很可能,你将使用bash shell,这是大多数发行版的默认值。 在终端会话期间,您可能经常重复常用命令,并且更频繁地键入这些命令的变体。虽然在开始时再次键入每个命令可能是一个好的做法,但在某些时候,它跨越线会变成破坏性和烦恼。 幸运的是,bash shell有一些相当发达的历史功能。学习如何有效地使用和操纵你的bash历史将允许你花更少的时间打字和更多的时间完成实际工作。许多开发人员熟悉DRY哲学的Do not Repeat Yourself。有效使用bash的历史允许你更接近这个原则,并将加快你的工作流程。 在本指南中,我们将在Ubuntu 12.04 VPS实例上检查这些功能,但几乎所有现代Linux发行版都应以类似的方式运行。让我们开始吧!

设置历史记录默认值

在我们开始实际使用历史之前,让我们调整一些bash设置,使它更有用。 Bash允许您调整它在历史记录中存储的先前命令的数量。 它实际上是有这两个不同的选择: HISTFILESIZE参数配置多少命令保存在历史记录文件,而 HISTSIZE控制存储在内存中当前会话的数目。 这意味着您可以为当前会话的内存中的历史记录大小设置合理的上限,并将更大的历史记录保存到磁盘,以便稍后查看。默认情况下,bash中设置这些选项 非常保守 价值观,所以我们将扩大他们采取一个更大的历史优势。一些发行版已经增加了默认bash历史记录设置以及稍微更宽松的值。 打开你 ~/.bashrc用一个编辑器文件来更改这些设置:
nano ~/.bashrc
搜索两个 HISTSIZEHISTFILESIZE参数。如果已设置,请随意修改值。如果这些参数不在您的文件中,请立即添加。为了我们的目的,我们可以轻松地将10000行存储到磁盘,并将最后5000行存入内存。这是大多数系统的保守估计,但如果您看到性能影响,请将其调整:
HISTSIZE=5000
HISTFILESIZE=10000
默认情况下,bash在每个会话结束时写入其历史记录,用更新的版本覆盖现有文件。这意味着如果您使用多个bash会话登录,则只有最后一个要退出的会话将保存其历史记录。 我们可以通过设置变通解决此 histappend设置,这将追加代替改写的历史。这可能已经设置,但如果不是,您可以通过添加以下行来启用:
shopt -s histappend
如果我们想要有立即的bash命令添加到我们的历史,而不是等待每个会话(以使在一个终端命令即刻出现在其他)结束后,我们还可以设置或追加 history -a命令来 PROMPT_COMMAND参数,它包含了每一个新的命令提示符之前执行的命令。 要正确地做到这一点,我们需要做一点黑客。我们需要追加立即与历史文件 history -a ,清除当前的历史在我们与会话 history -c ,然后读取,我们已经追加到,回到我们的会话历史记录历史记录 文件 history -r 。 你可以这样做:
export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"
完成后,保存文件并退出。 要实施更改,请先退出并重新登录,或通过键入以下内容来源文件:
source ~/.bashrc

查看您的上一个Bash历史记录

我们回顾历史的bash的方式是使用 history命令。 这将打印出我们最近的命令,每行一个命令。 这应该输出,最多时,您选择的行数为 HISTSIZE变量。在这一点上可能会更少:
history
   . . .
   43  man bash
   44  man fc
   45  man bash
   46  fc -l -10
   47  history
   48  ls -a
   49  vim .bash_history 
   50  history
   51  man history
   52  history 10
   53  history
它还打印每个命令的历史记录号。每个命令都与一个数字相关联,以便于参考。你会看到为什么这是有用的片刻。 我们可以通过在命令后指定一个数字来截断输出。例如,如果我们只想看到输入的最后5个命令,我们可以键入:
history 5
   50  history
   51  man history
   52  history 10
   53  history
   54  history 5
要找到涉及某个字符串的所有历史命令,一个简单的获得概述的方法是简单地管道它到grep。例如,我们可以搜索具有线 cd通过键入:
history | grep cd
   33  cd Pictures/
   37  cd ..
   39  cd Desktop/
   61  cd /usr/bin/
   68  cd
   83  cd /etc/
   86  cd resolvconf/
   90  cd resolv.conf.d/

从你的Bash历史执行命令

打印出我们的历史是很好的,但它本身并不真正帮助我们轻松地访问这些命令,除非作为参考。但是,我们可以使用特殊语法快速回调任何返回的输出。 我们可以回忆任何我们以前的历史,其前面有一个惊叹号(!)。例如,如果你的历史记录看起来像我上面那样,你可以通过键入以下内容快速看到history命令的手册页:
!51
这将立即调用并执行与历史号码51相关联的命令。 我们还可以执行相对于我们当前位置的命令。我们可以通过这样做 !-n语法,其中“n”是由命令前,我们要调出的号码代替。 举例来说,如果我们要调用和执行,我们在我们最近的一次键入的命令,我们可以输入 !-2 。因此,如果我们列出了一个长目录路径的内容,回显一些东西,并想再次列出,我们的会话可能看起来像这样:
ls /usr/share/doc/manpages
echo hello
!-2             # lists the contents again
要重新执行上面的命令,bash中提供了一条捷径,我们可以用代替 !-1 。 该快捷方式 !! ,这将取代最近执行的命令并执行:
!!
许多人使用这个,当他们键入一个命令,他们意识到他们需要sudo权限执行。打字 sudo !!会在它的前面使用sudo重新执行该命令。会话可能如下所示:
touch /etc/hello
touch: cannot touch `/etc/hello': Permission denied
sudo !!
sudo touch /etc/hello
[sudo] password for demouser:
这演示了此语法的另一个属性。它们是纯粹的替换,并且可以随意并入其他命令中。

滚动浏览Bash History

有几种方法,我们可以滚动我们的bash历史,把每个连续的命令在命令行上编辑。 最常用的方法是在命令提示符下按向上箭头键。 每次额外按向上箭头键将进一步回到您的命令行历史记录。如果你需要走另一个方向,向下箭头键在相反方向上移动历史记录,最后让你回到当前提示。 如果所有的方式在移动你的手箭头键似乎是一个大麻烦,你可以向后你的命令历史记录使用移动 CTRL-p的组合,并使用 CTRL-n组合,在历史上又向前迈进。 如果你想跳回到当前的命令提示符下,您可以通过键入这样做 Meta-> 。 在大多数情况下,“元”键和“>”将意味着输入 ALT-Shift-.如果你发现自己早在你的历史,要回到你当前命令,这很有用。 您可以通过执行相反的动作,然后输入到您的命令历史记录的第一行 Meta-< 。 这通常意味着按 ALT-Shift-, 总而言之,这些是滚动历史记录并跳到任一端的一些键:
  • 向上箭头键 :在历史向后滚动
  • CTRL-P:在历史向后滚动
  • 向下箭头键 :在历史向前滚动
  • CTRL-N:在滚动向前的历史
  • ALT-按住Shift:跳转到历史的终结(最新)
  • ALT-按住Shift,:跳转到历史的开头(最远距离)

搜索Bash历史记录

虽然管道的 history ,通过grep命令肯定是完成一些程序的最简单的方法,它是不是在很多情况下的理想选择。 Bash包括其历史的搜索功能。利用这种典型的方式是通过在历史反向搜索使用(最近的结果显示在最前面), CTRL-r组合键。 例如,您可以键入 CTRL-r并开始键入前一个命令的一部分。 你只需要输入部分命令。 如果匹配不需要的命令来代替,可以按 CTRL-r再次看到未来的结果。 如果你不小心通过你想要的命令,你可以通过键入向相反的方向移动 CTRL-s如果您使用上一部分中的键移动到历史记录中的其他点,并希望向前搜索,这也很有用。 注意 :在许多码头, CTRL-s实际上映射到暂停终端会话。 这将拦截任何企图通过 CTRL-s抨击,并“冻结”你的终端。 要解冻,只需键入 CTRL-q来取消挂起的会话。 这种暂停和恢复功能在大多数现代终端不需要,我们可以关闭没有任何问题,键入:
stty -ixon
我们应该将它添加到我们 ~/.bashrc文件,以使这种更改永久为好。 如果你再试一次,它应该按预期工作,让你向前搜索。

在键入命令之后搜索

找到自己的常见场景是输入命令的一部分,然后意识到您以前执行过它,并且可以搜索它的历史记录。 使用的是什么已经在您的命令行是你的光标移动到与行的开始搜索的正确方法 CTRL-a调用与反向历史 CTRL-r当前的行粘贴到与搜索 CTRL-y然后使用 CTRL-r再次以相反的搜索。 例如,假设我们要在Ubuntu系统上更新我们的包缓存。我们已经输入了这一点,最近,但我们没有想到直到经过我们所输入的 sudo再次:
sudo
在这一点上,我们意识到这是我们在过去一天左右所做的一个操作。我们可以打:
CTRL-a
这将我们的光标移动到行的开始。
CTRL-r
我们称之为反向增量历史搜索。这有副作用,复制在我们的光标位置之后的命令行上的所有内容。它把这放入剪贴板。
CTRL-y
我们将刚刚从命令行复制的命令段粘贴到搜索中。
CTRL-r
我们在历史中向后移动,搜索包含我们刚刚粘贴的内容的命令。 这可能看起来像一个巨大的痛苦的脖子,但它实际上并不太糟糕,当你习惯它。这是非常有帮助的,当你发现自己在那个尴尬的位置,你输入了一半的复杂的命令,知道你需要历史完成休息。 为了使它更容易,你可以认为这是一个更简单的复合命令:
CTRL-aryr

熟悉更多高级历史扩展

我们已经谈到了bash提供的一些最基本的历史扩展技术。到目前为止,我们介绍的一些是:
  • !!:扩展为最后一个命令
  • !N:扩大与历史编号“n”的指挥。
  • !-n:展开了历史上当前命令之前,命令的命令,这是“N”号。

事件指示器

上述三个例子是 事件标志的实例。这些通常是使用某些标准调用先前历史命令的方式。它们是我们可用操作的选择部分。 我们可以通过键入以下内容来执行最后的“ssh”命令:
!ssh
这将搜索以“ssh”开头的行。如果我们要搜索在命令开头没有发生的字符串,我们可以用“?”个字符。例如,要重复我们最 apt-cache search命令,我们也许可以打字逃脱:
!?search?
你可以尝试另一个窍门是在变化 !!上一条历史命令。您可以通过键入以下内容进行快速搜索和替换:
^original^replacement^
这将调用以前的命令(就像“!!”),在命令字符串中搜索“原始”的实例,并将其替换为“替换”。然后它将执行命令。 这对于处理拼写错误等事情很有用。例如:
cat /etc/hosst
cat: /etc/hosst: No such file or directory
^hosst^hosts^

字指示符

事件标志后,我们可以添加一个冒号(:),并添加就一个 字desginator来选择匹配的命令的一部分。 它通过将命令分成“字”来实现,这些字被定义为由空格分隔的任何块。这使我们有一些有趣的机会与我们的命令参数进行交互。 单词编号从初始命令开始,为“0”,第一个参数为“1”,并从那里继续。 例如,我们可以列出目录的内容,然后决定我们要改变它,像这样:
ls /usr/share/doc/manpages
cd !!:1
在我们对最后一个命令进行操作的情况下,我们可以通过删除第二个“!”和冒号来压缩它,如下所示:
cd !1
这将以相同的方式操作。 我们可以将第一个参数称为“^”,最后一个参数为“$”,如果这对我们的目的有意义。当我们使用范围而不是特定的数字时,这些更有用。例如,我们有三种方法可以将所有参数从前一个命令转换为新的命令:
!!:1*
!!:1-$
!!:*
孤独的 “,”扩展到被召回命令的所有部分比最初命令等。 同样,我们可以用一个数字后面加上“”,以表示指定的字后,一切都应该被包括在内。

修饰符

我们可以做的增强历史行的行为的最后一件事是我们要回忆的是修改召回的行为来操纵文本本身。修饰符在扩展末尾添加一个冒号(:)字符后面。 例如,我们可以通过使用“h”修饰符(它代表“head”)来删除导向到文件的路径,这会删除路径,直到最后一个斜杠(/)字符。请注意,如果您使用此方法截断目录路径,并且路径以尾部斜线结尾,则这将无法按照您希望的方式工作。 一个常见的用例是,如果我们正在修改一个文件,并意识到我们想改变到文件的目录来做相关文件的操作。 例如,我们可以读取包的版权信息:
cat /usr/share/doc/manpages/copyright
在满意我们可以使用这个包以满足我们的需求之后,我们可能想要改变到目录。我们可以通过调用为此 cd上的说法指挥系统,并在年底斩去文件名:
cd !!:$:h
pwd
/usr/share/doc/manpages
在我们到达之后,我们可能希望再次打开该版权文件以进行复查,这次在寻呼机中。 我们可以做反向操作,切断路径并且只使用带有“t”修饰符的文件名作为“tail”。我们可以搜索我们最后 cat的操作,并使用“T”标志仅传递文件名:
less !cat:$:t
您可以轻松地保留完整的绝对路径名,并且此命令在此实例中将正常工作。然而,还有其他一些时候,这是不正确的。我们可以使用相对路径查看嵌套在当前目录下面的几个子目录中的文件,使用“h”修饰符更改为子目录,然后我们将无法依赖相对路径名称到达该文件了。 另一个非常有用的修饰符是“r”修饰符,用于剥离尾部扩展名。这可能是有用的,如果您使用tar解压缩文件,并希望更改到目录后。假设生成的目录与文件名称相同,您可以执行以下操作:
tar xzvf long-project-name.tgz
cd !!:$:r
如果你的压缩包使用 tar.gz扩展,而不是 tgz ,你可以通过修改两次:
tar xzvf long-project-name.tar.gz
cd !!:$:r:r
类似的修饰符“e”除去尾部扩展名之外的所有内容。 如果你不想执行你正在调用的命令,而只是希望找到它,你可以使用“p”修饰符让bash echo命令,而不是执行它。 如果您不确定是否选择了正确的作品,这将非常有用。这不仅打印它,而且把它放在你的历史进一步编辑,如果你不满意。 例如,假设您在主目录上运行find命令,然后意识到要从根目录(/)运行它。你可以检查你是否正确的替换像这样(假设原来的命令是#119):
find ~ -name "file1"    # original command
!119:0:p / !119:2*:p
find / -name "file1"
如果输出的命令我们拼凑在一起是正确的,我们可以很容易地执行:
CTRL-p
这可能会更容易,如果我们可以轻松地在我们的命令替换。我们可以做到这一点使用 s/original/new/语法。 例如,我们可以通过输入:
!119:s/~/\//
这将替换搜索模式的第一个实例。我们可以通过将“g”标志与“s”传递来替换每个匹配。例如,如果我们要创建名为file1,file2和file3的文件,然后想创建名为dir1,dir2,dir3的目录,我们可以这样做:
touch file1 file2 file3
mkdir !!:*:gs/file/dir/

结论

您现在应该知道如何利用可用的历史操作。其中一些可能会比其他人更有用,但是很高兴知道bash有这些能力,以防你发现自己在一个位置,这将有助于挖掘它们。 如果没有别的,历史命令,反向搜索和简单的历史扩展应该帮助你加快你的工作流程。
作者:Justin Ellingwood
赞(52) 打赏
未经允许不得转载:优客志 » 系统运维
分享到:

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏