Linux命令行下感叹号的几个用法
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命令行下感叹号的几个用法相关推荐
- linux命令行下命令参数前的一横(-)和两横(--)的区别
linux命令行下命令参数前的一横(-)和两横(--)的区别 原文转自:http://blog.csdn.net/songjinshi/article/details/6816776 在解释这些区别之 ...
- ffmpeg linux 命令,Linux命令行下转换媒体格式工具FFMPEG介绍
Linux命令行下转换媒体格式工具FFMPEG介绍 格式:ffmpeg [[输入文件选项]- i 输入文件名] {[输入文件选项] 输出文件名} 主要选项: -L 显示ffmpeg的版权说明 -h 显 ...
- linux命令行下载github文件,Linux命令行下使用GitHub
Linux命令行下使用GitHub 1.注册github账号 2.创建ssh密钥 cd ~ ssh-keygen -t rsa -C your_email@example.com 1 2 cd~ ss ...
- linux 命令api,linux命令行下字典,使用有道API
Linux命令行下的字典,使用"exit"退出.大家简单申请一个key就可以用了. 这里 申请 #!/usr/bin/python3.2 import urllib.request ...
- 【转】Linux命令行下svn ignore忽略文件或文件夹用法
转自:Linux命令行下svn ignore忽略文件或文件夹用法 - 陌上归人的博客 - 博客园 一.忽略单个目录 1.忽略文件夹 假如目录oa.youxi.com是从svn checkout出来的, ...
- linux 的一些实用工具,linux 命令行下的一些实用工具
linux 命令行下的一些实用工具 命令行下的一些常用应用: awesome 适合geek的桌面管理器VM mc ...
- linux的manual手册不存在,在 Linux 命令行下使用“原力”
原标题:在 Linux 命令行下使用"原力" 和绝地武士的原力一样,-f 参数是很强大的,并伴随着潜在的毁灭性,在你能用好的时候又很便利. -- Alan Formy-duval( ...
- linux 命令行下导出查询的数据
linux 命令行下导出查询的数据 因为业务要求只能在 linux 命令行下导出数据,所需需要此命令导出 mysql -uroot -p'password' mika_gxgd -e "SE ...
- 详解Linux命令行下常用svn命令
2019独角兽企业重金招聘Python工程师标准>>> 本文讲述了Linux命令行下常用svn命令的使用方法,希望对您有所帮助. 1.Linux命令行下将文件checkout到本地目 ...
最新文章
- H5开发开发利器——flex
- 1045: 愚人节的礼物
- cad.net 获取所有已经安装的cad版本信息
- Visual Studio 支持 Java?谣言止于智者
- 逻辑回归的通俗解释 逻辑回归的定位
- 一份关于如何为回归任务选择机器学习算法指南
- python算法的缺陷和不足_决策树基本概念及算法优缺点
- MYSQL limit 分页
- (个人简历一)用纯html写个人简历
- 如何做一个阿里云物联网安卓原生APP
- Excel做数据分析?是真的很强
- 怀旧服服务器维护以后精英怪,《魔兽世界》:看不起怀旧服精英怪,一定吃不了兜着走...
- SpringBoot中使用MyBatis-Plus是如何解决Invalid bound statement (not found)这个异常的
- filtering_audio.c/filtering_video.c 解读
- css背景立变立体感
- 堆内存(heap)和栈内存(stack)区别
- 利用poi 1.6 通过模板导出复杂 Word表格,包含合单元格后垂直居中、循环生成行等
- Electron在win7上加载plotyjs失败的解决方法
- Verilog HDL 实验题
- Firefox for Android 代理设置
热门文章
- linux 环境 RocketMQ 4.8.0 安装、部署控制台
- 使用xfire webservice接口开发,obj与xml相互转换好用工具类,不需要写大量的转换代码,亲测可用
- idea 利用vue.js插件创建vue初始化项目
- PLSQL 设置布局
- SpringCloud企业实战专栏
- VBA IsNull 应用 - 捕获错误并查找未填充的值
- Vue中computed和watch的区别(面试题)
- Leetcode 349.两个数组交集(哈希容器unordered_set)
- php 类似微信下拉菜单,微信小程序模拟下拉菜单开发实例
- C语言 goto 语句 - C语言零基础入门教程