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/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/532652.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

三地址码简介

三地址码简介 三地址码(Three Address Code)是一种最常用的中间语言,编译器可以通过它来改进代码转换效率。每个三地址码指令,都可以被分解为一个四元组(4-tuple)的形式:(运算符&am…

llvm与gcc

llvm与gcc llvm 是一个编译器,也是一个编译器架构,是一系列编译工具,也是一个编译器工具链,开源 C11 实现。 gcc 相对于 clang 的优势: gcc 支持更过语言前端,如 Java, Ada, FORTRAN, Go等gcc 支持更多地 …

攻防世界web新手区解题 view_source / robots / backup

1**. view_source** 题目描述:X老师让小宁同学查看一个网页的源代码,但小宁同学发现鼠标右键好像不管用了。 f12查看源码即可发现flag 2. robots 题目描述:X老师上课讲了Robots协议,小宁同学却上课打了瞌睡,赶紧来教教…

python参数传递*args和**kwargs

python参数传递*args和**kwargs 和* 实际上真正的Python参数传递语法是 * 和 ** 。*args 和 **kwargs 只是一种约定俗成的编程实践。我们也可以写成 *vars 和 **kvars 。就如同其他常规变量的命名一样, args 和 kwargs 只是一种习惯的名称。 *args 和 **kwargs 一…

听GPT 讲Rust源代码--src/tools(25)

File: rust/src/tools/clippy/clippy_lints/src/methods/suspicious_command_arg_space.rs 在Rust源代码中,suspicious_command_arg_space.rs文件位于clippy_lints工具包的methods目录下,用于实现Clippy lint SUSPICIOUS_COMMAND_ARG_SPACE。 Clippy是Ru…

Java一次编译,到处运行是如何实现的

Java一次编译,到处运行是如何实现的 转自:https://cloud.tencent.com/developer/article/1415194 (排版微调) JAVA编译运行总览 Java是一种高级语言,要让计算机执行你撰写的Java程序,也得通过编译程序的…

JIT(动态编译)和AOT(静态编译)编译技术比较

JIT(动态编译)和AOT(静态编译)编译技术比较 转自:https://www.cnblogs.com/tinytiny/p/3200448.html Java 应用程序的性能经常成为开发社区中的讨论热点。因为该语言的设计初衷是使用解释的方式支持应用程序的可移植…

python解释器

python解释器 计算机编程语言 本部分参考自:https://zhuanlan.zhihu.com/p/141212114 从计算机编程语言说起,它主要分为三类:机器语言、汇编语言、高级语言。 机器语言是一种计算机可以直接识别并执行的二进制指令集。由于其可以直接交给…

编译型语言与解释型语言

编译型语言与解释型语言 首先要说明,编译型语言与解释型语言这种分类方法是不科学的,或者说已经过时了,但是这种称呼大抵还是能够让人明白我们将要讨论的是什么东西。 文中所列参考是笔者认为比较有帮助的一些扩展阅读内容。 首先贴一个很形…

常见的各种shell及其区别

常见的各种shell及其区别 引子 for((i1;i<10;i)); do echo $(expr $i \* 3 1); done 网上搜到的 shell for循环脚本&#xff0c;别人都能正常运行&#xff0c;我却报错&#xff1a; Syntax error: Bad for loop variable究竟是怎么回事呢&#xff1f; shell简介…

shell脚本 变量

shell脚本 变量类型 什么是Shell变量 用一个固定的字符串去表示不固定的内容。 Shell变量的类型 shell脚本中自定义变量的类型&#xff0c;我们这里分为&#xff1a; 自定义变量环境变量位置变量与定义变量 这四类&#xff0c;它们有一些相同点&#xff0c;但又有些不同点…

攻防世界web新手区解题 /cookie / disabled_button / weak_auth

cookie 题目描述&#xff1a;X老师告诉小宁他在cookie里放了些东西&#xff0c;小宁疑惑地想&#xff1a;‘这是夹心饼干的意思吗&#xff1f;’ 使用burp suite抓包查看 发现提示&#xff1a; look-herecookie.php 于是在url后加上 cookie.php 得到提示查看返回 就得到了f…

Python 函数式编程

Python 函数式编程 转自&#xff1a;https://www.liaoxuefeng.com/wiki/1016959663602400/1017328525009056&#xff0c;推荐去该链接读原文&#xff0c;有习题和热烈的评论区交流。 函数式编程 函数是Python内建支持的一种封装&#xff0c;我们通过把大段代码拆成函数&…

Python中的生成器与迭代器

Python中的生成器与迭代器 转自&#xff1a;https://www.liaoxuefeng.com/wiki/1016959663602400/1017323698112640&#xff0c;推荐去该链接读原文&#xff0c;有习题和热烈的评论区交流。 生成器 通过列表生成式&#xff0c;我们可以直接创建一个列表。但是&#xff0c;受…

基于GET报错的sql注入,sqli-lab 1~4

根据注入类型可将sql注入分为两类&#xff1a;数字型和字符型 例如&#xff1a; 数字型&#xff1a; sleect * from table where if 用户输入id 字符型&#xff1a;select * from table where id 用户输入id &#xff08;有引号) 通过URL中修改对应的D值&#xff0c;为正常数字…

Python 装饰器详解(上)

Python 装饰器详解&#xff08;上&#xff09; 转自&#xff1a;https://blog.csdn.net/qq_27825451/article/details/84396970&#xff0c;博主仅对其中 demo 实现中不适合python3 版本的语法进行修改&#xff0c;并微调了排版&#xff0c;本转载博客全部例程博主均已亲测可行…

xss原理和注入类型

XSS漏洞原理 : XSS又叫CSS(cross Site Script), 跨站脚本攻击,指的是恶意攻击者往Web页面里插入恶意JS代码,当用户浏览该页时,嵌入其中的Web里的JS代码就会被执行,从而达到恶意的特殊目的. 比如:拿到cooike XSS漏洞分类: 反射性(非存储型) payload没有经过存储,后端接收后,直接…

Python 装饰器详解(中)

Python 装饰器详解&#xff08;中&#xff09; 转自&#xff1a;https://blog.csdn.net/qq_27825451/article/details/84581272&#xff0c;博主仅对其中 demo 实现中不适合python3 版本的语法进行修改&#xff0c;并微调了排版&#xff0c;本转载博客全部例程博主均已亲测可行…

存储型xss案例

存储型xss原理: 攻击者在页面插入xss代码,服务端将数据存入数据库,当用户访问存在xss漏洞的页面时,服务端从数据库取出数据展示到页面上,导致xss代码执行,达到攻击效果 案例: 在一个搭建的论坛网站中, 根据存储型xss注入的条件,要找到可以存储到数据库的输入位置,并且这个位置…

反射型XSS案例

**原理:**攻击者将url中插入xss代码,服务端将url中的xss代码输出到页面上,攻击者将带有xss代码的url发送给用户,用户打开后受到xss攻击 需要url中有可以修改的参数 案例: 可能存在反射型xss的功能(点) : 搜索框等&#xff08;所有url会出现参数的地方都可以尝试&#xff09;……