Linux命令行下 " ! " 的几个用法

! 在大多数编程语言中表示取反的意思,但是在命令行中,他还有一些其他的神奇用法。熟练掌握这些用法,可以大大提高我们日常命令行操作的效率。

1 执行历史命令

!!

! 在命令行中可以用来执行历史命令,最常用的,大家应该比较熟悉的是执行上一条命令 !!,它可以用来执行最近的一条命令。

该命令在我们忘记使用 root 权限执行某项命令时很有用:sudo !! 在上一条命令之前加 root 权限再执行。

比如,我们要用 fdisk 命令查看磁盘信息,但是如果没有 root 权限是会被拒绝的,这时我们就可以直接 sudo !!

$ fdisk -l
fdisk: cannot open /dev/loop0: Permission denied
# ...
fdisk: cannot open /dev/loop30: Permission denied
fdisk: cannot open /dev/loop31: Permission denied
$ sudo !!
sudo fdisk -l
[sudo] password for song:
Disk /dev/loop0: 4.2 MiB, 4448256 bytes, 8688 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
# ...

或者在我们忘记加某项参数时,也可以通过 !! -p 来快速添加参数执行上一条命令。比如我要 gdb 调试某个源文件,但是忘了加 -g 参数,即可:

g++ quickSort.cpp
!! -g

有趣的是,!! 符号可以理解为完整地重复上一条指令的文本,即使在有些时候语义不连贯也是可行的。比如下面这个情景。

在当前目录下,我们有 tsne.py 和 tsne.png 两个文件,这时我想要 vim 修改 tsne.py 的内容,很有可能会手快通过 tab 键执行这样的命令:vim tsne.p,这时我们可以直接 !!y,就能顺利地执行 vim tsne.py

!n

!! 命令虽然很好用,但是它只能执行上面最近一条命令,那么能不能执行上面几条(如倒数第二条、倒数第三条)指令呢,又能不能有一个一般的命令,来执行某一条历史命令呢?当然是有的!

首先,我们知道 history 命令可以查看最近的历史命令。值得注意的是,它显示的每条历史命令之前会有一个编号,我们好像在平常没太注意过这个编号有什么作用:

$ history2083  ls2084  vim quickSort.cpp2085  g++ quickSort.cpp2086  g++ quickSort.cpp  -g2087  history

实际上,我们可以直接通过这个编号来执行某条历史命令,如 !2084

这个用法好像比较鸡肋,因为历史命令编号我们很少回去记住它,每次要用 history 命令查,再执行的话未免有些麻烦。笔者一时能想到的应用场景是如果我们在一段时间(比如一小时、一下午)内,要重复的用某条超复杂的命令(比如很长的路径名),我们不妨短时记忆一下某个历史命令编号,并多次使用该编号执行历史命令。

比如我今天下午调试程序时要多次修改某个 py 文件,就可以记住这个命令的编号,然后每次 !1994 来执行历史命令。

 1994  vim /home/ps/JJ_Projects/ssl_transformer_aes/my_project/SiT/pretrain_ssl.sh

!-i

!-i 的形式可以执行倒数第 i 条命令。如 !-6!-8等。特别地,!-1 就相当于 !!

!cmd

!cmd 通过关键词来执行历史命令。可以按照下面的命令来理解:

$ ls /home > /dev/null
$ ls -l /home/song/JJ_Projects/ > /dev/null
$ ls -la /home/song/JJ_Projects/ > /dev/null
$ ls -lA /usr/bin > /dev/null

上面是相同的ls命令对应了不同参数和文件夹。此外我们将每一个标准输出都传递到了 /dev/null 因为我们并不希望处理程序的标准输出。现在我们可以调用命令的关键词来实现它们。

$ !ls
$ !ls -l
$ !ls -la
$ !ls -lA

当你使用 !ls 关键词来执行之前命令的时候,你一定会被标准输出给惊讶到。

2 复用历史参数

!$和!^

如同 !! 来执行上一条命令一样,!$!^ 也是很常用的,它们的作用是重复上一条命令的第一个或最后一个参数。

!$ 为例,考虑这样的场景,我要删除某个目录下的所有 png 图像文件,但是在删除之前,我要先查看一下,确定这些图像文件确实都是没有用的。可以这样操作:

ls /home/song/JJ_Projects/ava-mlsp/metadata/*.png
rm !$

这样能省去我们重复上一个命令操作参数的时间。

另一个更普遍的场景:当我们编辑完 ~/.bashrc 文件后,需要用 source 命令使它生效,此时可以:

vim ~/.bashrc
# 一顿操作,修改 .bashrc 文件内容
source !$

!cmd:n

同样的,我们将 !$!^ 推广到一般情况,!cmd:n :获取最近一次 cmd 命令的第 n 个参数(参数的个数从 0 开始计)。

如:

ls -a -l
ls !ls:1

这样后面一条命令相当于执行了:ls -l

3 取反

! 在很多编程语言中都是取反的意思,!= 也通常都是不等于的意思。

在逻辑判断中取反

同大多数编程语言一样,! 在 shell 脚本中表示取反的意思。

[ ! -d /home/song/JJ_Prjects ] 可以用来判断该目录是否为空。

在命令中取反

rm !(train.py) 可以删除当前目录下除了 train.py 之外的全部文件。rm !(*.png) 删除当前目录下除了后缀名为 png 之外的全部文件。

总结起来最常用的除了在编程时取反之外,在命令行中用起来比较丝滑的也就是 !!!$,它们的推广的更一般的形式虽然能实现的功能更全面,但稍显麻烦,不太常用。以上就是笔者对 ! 在命令行中使用的总结了,如果有错误或补充,欢迎留言讨论。

Ref:

https://linuxstory.org/mysterious-ten-operator-in-linux/

Linux命令行下感叹号的几个用法相关推荐

  1. linux命令行下命令参数前的一横(-)和两横(--)的区别

    linux命令行下命令参数前的一横(-)和两横(--)的区别 原文转自:http://blog.csdn.net/songjinshi/article/details/6816776 在解释这些区别之 ...

  2. ffmpeg linux 命令,Linux命令行下转换媒体格式工具FFMPEG介绍

    Linux命令行下转换媒体格式工具FFMPEG介绍 格式:ffmpeg [[输入文件选项]- i 输入文件名] {[输入文件选项] 输出文件名} 主要选项: -L 显示ffmpeg的版权说明 -h 显 ...

  3. linux命令行下载github文件,Linux命令行下使用GitHub

    Linux命令行下使用GitHub 1.注册github账号 2.创建ssh密钥 cd ~ ssh-keygen -t rsa -C your_email@example.com 1 2 cd~ ss ...

  4. linux 命令api,linux命令行下字典,使用有道API

    Linux命令行下的字典,使用"exit"退出.大家简单申请一个key就可以用了. 这里 申请 #!/usr/bin/python3.2 import urllib.request ...

  5. 【转】Linux命令行下svn ignore忽略文件或文件夹用法

    转自:Linux命令行下svn ignore忽略文件或文件夹用法 - 陌上归人的博客 - 博客园 一.忽略单个目录 1.忽略文件夹 假如目录oa.youxi.com是从svn checkout出来的, ...

  6. linux 的一些实用工具,linux 命令行下的一些实用工具

    linux 命令行下的一些实用工具 命令行下的一些常用应用: awesome                        适合geek的桌面管理器VM mc                     ...

  7. linux的manual手册不存在,在 Linux 命令行下使用“原力”

    原标题:在 Linux 命令行下使用"原力" 和绝地武士的原力一样,-f 参数是很强大的,并伴随着潜在的毁灭性,在你能用好的时候又很便利. -- Alan Formy-duval( ...

  8. linux 命令行下导出查询的数据

    linux 命令行下导出查询的数据 因为业务要求只能在 linux 命令行下导出数据,所需需要此命令导出 mysql -uroot -p'password' mika_gxgd -e "SE ...

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

    2019独角兽企业重金招聘Python工程师标准>>> 本文讲述了Linux命令行下常用svn命令的使用方法,希望对您有所帮助. 1.Linux命令行下将文件checkout到本地目 ...

最新文章

  1. H5开发开发利器——flex
  2. 1045: 愚人节的礼物
  3. cad.net 获取所有已经安装的cad版本信息
  4. Visual Studio 支持 Java?谣言止于智者
  5. 逻辑回归的通俗解释 逻辑回归的定位
  6. 一份关于如何为回归任务选择机器学习算法指南
  7. python算法的缺陷和不足_决策树基本概念及算法优缺点
  8. MYSQL limit 分页
  9. (个人简历一)用纯html写个人简历
  10. 如何做一个阿里云物联网安卓原生APP
  11. Excel做数据分析?是真的很强
  12. 怀旧服服务器维护以后精英怪,《魔兽世界》:看不起怀旧服精英怪,一定吃不了兜着走...
  13. SpringBoot中使用MyBatis-Plus是如何解决Invalid bound statement (not found)这个异常的
  14. filtering_audio.c/filtering_video.c 解读
  15. css背景立变立体感
  16. 堆内存(heap)和栈内存(stack)区别
  17. 利用poi 1.6 通过模板导出复杂 Word表格,包含合单元格后垂直居中、循环生成行等
  18. Electron在win7上加载plotyjs失败的解决方法
  19. Verilog HDL 实验题
  20. Firefox for Android 代理设置

热门文章

  1. linux 环境 RocketMQ 4.8.0 安装、部署控制台
  2. 使用xfire webservice接口开发,obj与xml相互转换好用工具类,不需要写大量的转换代码,亲测可用
  3. idea 利用vue.js插件创建vue初始化项目
  4. PLSQL 设置布局
  5. SpringCloud企业实战专栏
  6. VBA IsNull 应用 - 捕获错误并查找未填充的值
  7. Vue中computed和watch的区别(面试题)
  8. Leetcode 349.两个数组交集(哈希容器unordered_set)
  9. php 类似微信下拉菜单,微信小程序模拟下拉菜单开发实例
  10. C语言 goto 语句 - C语言零基础入门教程