在Linux命令行下令人惊叹的惊叹号(!)

‘!‘符号在Linux中不但可以用作否定符号,还可以用来从历史命令记录中取出命令或不加修改的执行之前运行的命令。下面的所有命令都已经在Bash Shell中经过确切地检验。尽管我没有试过,但大多都不能在别的Shell中运行。这里我们介绍下Linux命令行中符号‘!‘那惊人和奇妙的用法。

1. 使用数字从历史命令列表中找一条命令来执行

您也许没有意识到您可以从历史命令列表(之前已经执行的命令集)中找出一条来运行。首先,通过"history"命令查找之前命令的序号。

  1. $ history

使用history命令找到最后执行的命令

现在,只需要使用历史命令输出中显示在该命令前面的数字便可以运行这个命令。例如,运行一个在history输出中编号是1551的命令。

  1. $ !1551

使用命令ID来执行最后运行的命令

这样,编号为1551的命令(上面的例子是top命令)便运行了。这种通过ID号来执行之前的命令的方式很有用,尤其是在这些命令都很长的情况下。您只需要使用![history命令输出的序号]便可以调用它。

2. 运行之前的倒数第二个、第七个命令等

您可以以另一种方式来运行之前执行的命令,通过使用-1代表最后的命令,-2代表倒数第二个命令,-7代表倒数第七个命令等。

首先使用history命令来获得执行过的命令的列表。history命令的执行很有必要,因为您可以通过它来确保没有rm command > file或其他会导致危险的命令。接下来执行倒数第六个、第八个、第十个命令。

  1. $ history
  2. $ !-6
  3. $ !-8
  4. $ !-10

通过负数序号运行之前执行的命令

3. 传递最后执行的命令的参数,以方便的运行新的命令

我需要显示/home/$USER/Binary/firefox文件夹的内容,因此我执行:

  1. $ ls /home/$USER/Binary/firefox

接下来,我意识到我应该执行‘ls -l‘来查看哪个文件是可执行文件。因此我应该重新输入整个命令么?不,我不需要。我仅需要在新的命令中带上最后的参数,类似:

  1. $ ls -l !$

这里!$将把最后执行的命令的参数传递到这个新的命令中。

将上一个命令的参数传递给新命令

4. 如何使用!来处理两个或更多的参数

比如说我在桌面创建了一个文本文件file1.txt。

  1. $ touch /home/avi/Desktop/1.txt

然后在cp命令中使用绝对路径将它拷贝到/home/avi/Downloads

  1. $ cp /home/avi/Desktop/1.txt /home/avi/downloads

这里,我们给cp命令传递了两个参数。第一个是/home/avi/Desktop/1.txt,第二个是/home/avi/Downloads。让我们分别处理他们,使用echo [参数]来打印两个不同的参数。

  1. $ echo "1st Argument is : !^"
  2. $ echo "2nd Argument is : !cp:2"

注意第一个参数可以使用"!^"进行打印,其余的命令可以通过"![命令名]:[参数编号]"打印。

在上面的例子中,第一个命令是cp,第二个参数也需要被打印。因此是"!cp:2",如果任何命令比如xyz运行时有5个参数,而您需要获得第四个参数,您可以使用"!xyz:4"。所有的参数都可以通过"!*"来获得。

处理两个或更多的参数

5. 以关键字为基础执行上个的命令

我们可以以关键字为基础执行上次执行的命令。可以从下面的例子中理解:

  1. $ ls /home > /dev/null [命令1]
  2. $ ls -l /home/avi/Desktop > /dev/null [命令2]
  3. $ ls -la /home/avi/Downloads > /dev/null [命令3]
  4. $ ls -lA /usr/bin > /dev/null [命令4]

上面我们使用了同样的命令(ls),但有不同的开关和不同的操作文件夹。而且,我们还将输出传递到/dev/null,我们并未显示输出,因而终端依旧很干净。

现在以关键字为基础执行上个的命令。

  1. $ ! ls [命令1]
  2. $ ! ls -l [命令2]
  3. $ ! ls -la [命令3]
  4. $ ! ls -lA [命令4]

检查输出,您将惊奇发现您仅仅使用关键字ls便执行了您已经执行过的命令。

以关键字为基础执行命令

(LCTT 译注:澄清一下,这种用法会按照命令名来找到最后匹配的命令,不会匹配参数。所以上述执行的四个命令都是执行了 ls -lA /usr/bin > /dev/null,并增加了新的参数而已。)

6. !!操作符的威力

您可以使用(!!)运行/修改您上个运行的命令。它将附带一些修改/调整并调用上个命令。让我给您展示一些实际情境。

昨天我运行了一行脚本来获得我的私有IP,因此我执行了:

  1. $ ip addr show | grep inet | grep -v ‘inet6‘| grep -v ‘127.0.0.1‘ | awk ‘{print $2}‘ | cut -f1 -d/

接着,我突然发现我需要将上面脚本的输出重定向到一个ip.txt的文件,因此,我该怎么办呢?我该重新输入整个命令并重定向到一个文件么?一个简单的解决方案是使用向上光标键并添加‘> ip.txt‘来将输出重定向到文件。

  1. $ ip addr show | grep inet | grep -v ‘inet6‘| grep -v ‘127.0.0.1‘ | awk ‘{print $2}‘ | cut -f1 -d/ > ip.txt

在这里要感谢救世主"向上光标键"。现在,考虑下面的情况,这次我运行了下面这一行脚本。

  1. $ ifconfig | grep "inet addr:" | awk ‘{print $2}‘ | grep -v ‘127.0.0.1‘ | cut -f2 -d:

一旦我运行了这个脚本,Bash提示符便返回了错误消息"bash: ifconfig: command not found"。原因并不难猜,我运行了本应以root权限的运行的命令。

所以,怎么解决呢?以root用户登录并且再次键入整个命令就太麻烦了!而且向上导航键也不管用了(LCTT 译注:当你以新的用户身份登录了,是不能用向上光标键找到之前的另外一个用户的命令历史的)。因此,我们需要调用"!!"(去掉引号),它将为那个用户调用上个命令。

  1. $ su -c !! root

这里su是用来切换到root用户的,-c用来以某用户运行特定的命令,最重要的部分是!!,它将被替换为上次运行的命令。当然!您需要提供root密码。

!!操作符的威力

我通常在下面的情景中使用!!

当我用普通用户来运行apt-get,我通常收到提示说我没有权限来执行。

  1. $ apt-get upgrade && apt-get dist-upgrade

好吧,有错误。但别担心,使用下面的命令来成功的执行...

  1. $ su -c !!

同样的适用于:

  1. $ service apache2 start

  1. $ /etc/init.d/apache2 start

  1. $ systemctl start apache2

普通用户不被授权执行那些任务,这样相当于我运行:

  1. $ su -c ‘service apache2 start‘

  1. $ su -c ‘/etc/init.d/apache2 start‘

  1. $ su -c ‘systemctl start apache2‘

(LCTT 译注:使用!!之前,一定要确认你执行的是什么命令!另外,在 root 身份下,千万不要养成使用它的习惯,因为你总是会在不合适的目录执行不合适的命令!)

7.运行一个影响所有除了![FILE_NAME]的文件命令

!(逻辑非)能用来对除了‘!‘后的文件的所有的文件/扩展名执行命令。

A.从文件夹移除所有文件,2.txt除外。

  1. $ rm !(2.txt)

B.从文件夹移除所有的文件类型,pdf类型除外。

  1. $ rm !(*.pdf)

8.检查某个文件夹(比如/home/avi/Tecmint)是否存在?并打印

这里,我们使用‘! -d‘来验证文件夹是否存在,当文件夹不存在时,将使用其后跟随AND操作符(&&)进行打印,当文件夹存在时,将使用OR操作符(||)进行打印。

逻辑上,当[ ! -d /home/avi/Tecmint ]的输出为0时,它将执行AND逻辑符后面的内容,否则,它将执行OR逻辑符(||)后面的内容。

  1. $ [ ! -d /home/avi/Tecmint ] && printf ‘\nno such /home/avi/Tecmint directory exist\n‘ || printf ‘\n/home/avi/Tecmint directory exist\n‘

9.检查某文件夹是否存在?如果不存在则退出该命令

类似于上面的情况,但这里当期望的文件夹不存在时,该命令会退出。

  1. $ [ ! -d /home/avi/Tecmint ] && exit

10.如果您的home文件夹内不存在一个文件夹(比方说test),则创建它

这是脚本语言中的一个常用的实现,当期望的文件夹不存在时,创建一个。

  1. [ ! -d /home/avi/Tecmint ] && mkdir /home/avi/Tecmint

这便是全部了。如果您知道或偶尔遇到其他值得了解的‘!‘使用方法,请您在反馈的地方给我们提建议。保持联系!



via: http://www.tecmint.com/mysterious-uses-of-symbol-or-operator-in-linux-commands/

时间: 2024-10-13 19:01:06

在Linux命令行下令人惊叹的惊叹号(!)的相关文章

Linux命令行下cp,rm,mv命令的使用

以下的内容来源于<鸟哥的私房菜> Linux命令行下的复制.删除与移动:cp,rm,mv cp(copy)复制        cp这个命令的用途很多,除了单纯的复制之外,还可以创建链接文件对比两文件的新旧而予以更新,        以及复制整个目录等        语法            cp [-adfilprsu] 源文件 目标文件                    源文件(source)                目标文件(destination)            选项

Linux命令行下的vim文本编辑器

Linux命令行下的vim文本编辑器 vim文本编辑器是一个非常强大的工具,可以做很多事情,比如新建文件,打开文件,编辑文件,保存文件,同时打开多个文件等.下面总结一些常用的vim 编辑器命令: 1. 进入vim编辑器的方式:(进入vim编辑器时,默认的模式是“命令模式”) 在终端输入 vi:进入vim编辑器 vi filename:进入vim编辑器,新建了一个filename文件,光标定位到文件的第一行 vi在工作时,会在当前目录下创建.swp的临时文件,该临时文件也称为交换文件 当vi结束对

Linux命令行下编辑常用的快捷键

Linux命令行编辑快捷键: history                                   显示命令历史列表 ↑(Ctrl+p)                               显示上一条命令 ↓(Ctrl+n)                               显示下一条命令 !num                                     执行命令历史列表的第num条命令 !!                            

Linux命令行下svn ignore忽略文件或文件夹用法

Linux命令行下svn ignore忽略文件或文件夹用法 一.忽略单个目录 1.忽略文件夹 假如目录oa.youxi.com是从svn checkout出来的,在服务器本地目录添加了material,但是不希望把material加入版本控制,因此我们需要忽略掉这个目录首先使用svn status命令查看当前状态[[email protected] oa.youxi.com]# svn status? htdocs/admin/adv/material 添加需要忽略的目录,貌似必须得进入该目录之

详解Linux命令行下常用svn命令

1.Linux命令行下将文件checkout到本地目录 svn checkout path(path是服务器上的目录) 例如:svn checkout svn://192.168.1.1/pro/domain 简写:svn co 2.Linux命令行下往版本库中添加新的文件 svn add file 例如:svn add test.php(添加test.php) svn add *.php(添加当前目录下所有的php文件) 3.Linux命令行下将改动的文件提交到版本库 svn commit -

Linux命令行下如何终止当前程序?

Linux命令行下如何终止当前程序? 快捷键: Ctrl+c 在命令行下起着终止当前执行程序的作用, Ctrl+d 相当于exit命令,退出当前shell Ctrl+s 挂起当前shell(保护作用很明显哦) Ctrl+q 解冻挂起的shell再不行就重新连接打开一个终端,reboot linux 或 kill 相关进程. 原文地址:https://www.cnblogs.com/pythonClub/p/10914338.html

Linux 命令行下的好东西

  列举你可能没注意过的好用的 Linux 命令行命令 现在做网站做移动应用最讲究的就是推广了,推广做的好那就成功了一大半,相对的没曝光产品再好也很难做下去.就这个角度而言绝大多数 Linux 命令行的推广简直是烂透了.繁多 Linux 有用极了的命令行工具就静静的躺在你发行版默认安装的包裹里,很多时候只有当你碰到什么问题的时候网上搜一圈才能知道.更蛋疼的是这里面很多东西你一旦知道了就会想我靠原来没这个到底是怎么过的下去.所以这里我会列出一些我用过的一些,大部分发行版默认就有,或者能用包裹管理工

Linux 命令行下的最佳文本编辑器

文本编辑软件在任何操作系统上都是必备的软件.我们在 Linux 上不缺乏非常现代化的编辑软件,但是它们都是基于 GUI(图形界面)的编辑软件. 正如你所了解的,Linux 真正的魅力在于命令行.当你正在用命令行工作时,你就需要一个可以在控制台窗口运行的文本编辑器. 正因为这个目的,兄弟连Linux培训专门准备了一个基于 Linux 命令行的文本编辑器清单. VIM 如果你已经使用 Linux 有一段时间,那么你肯定听到过 Vim .Vim 是一个高度可配置的.跨平台的.高效率的文本编辑器. 几乎

Linux命令行下的快捷键

1. 命令行下的快捷键 经常在命令行下工作的同志们,可能用的最多的就是两个上下键,主要用来调出历史命令:使用左右箭头使光标向后或向前移动以修改上次使用过的命令.其实这样做效率并不是很高,有了快捷键可以让我们的效率有所提高,而且看起来还更专业.更加Awesome.更加Geek.掌握了这些快捷键,我们可以做到手不离主键盘区域,完全可以忽略掉键盘上的四个可爱的箭头.当我们熟练之后,会越发喜欢这种方式. 1.1 常用快捷键介绍 下面介绍一些作者在命令行下经常使用的快捷键,这些快捷键在Emacs下面是有同