Shell中特殊符号的用法汇总

记录一下一些特殊符号如$/!/~在shell(泛指bash)中的用法

事件指示符 - Event Designators

!N

说明

执行第N行的命令

样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@ip-10-35-16-55 ~]# history |tail -5
1000 history |tail -10
1001 ps -ef
1002 ll /tmp
1003 systemctl status docker
1004 history |tail -5
[root@ip-10-35-16-55 ~]# !1001
ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 Aug05 ? 00:13:11 /usr/lib/systemd/systemd --system --deserialize 22
root 2 0 0 Aug05 ? 00:00:00 [kthreadd]
root 4 2 0 Aug05 ? 00:00:00 [kworker/0:0H]
root 6 2 0 Aug05 ? 00:00:00 [mm_percpu_wq]
root 7 2 0 Aug05 ? 00:00:31 [ksoftirqd/0]
....

!-N

说明

执行倒数N行的命令

样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@ip-10-35-16-55 ~]# history |tail -5
1002 ll /tmp
1003 systemctl status docker
1004 history |tail -5
1005 ps -ef
1006 history |tail -5
[root@ip-10-35-16-55 ~]# !-2
ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 Aug05 ? 00:13:11 /usr/lib/systemd/systemd --system --deserialize 22
root 2 0 0 Aug05 ? 00:00:00 [kthreadd]
root 4 2 0 Aug05 ? 00:00:00 [kworker/0:0H]
root 6 2 0 Aug05 ? 00:00:00 [mm_percpu_wq]
....

!!

说明

执行上一次的命令, 等价于!-1

样例

1
2
3
4
5
6
7
[ec2-user@ip-10-35-16-55 ~]$ yum update
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
You need to be root to perform this command.
[ec2-user@ip-10-35-16-55 ~]$ sudo !!
sudo yum update
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
....

!COMMAND

说明

执行上一个以COMMAND开头的命令

样例

1
2
3
4
5
6
7
[ec2-user@ip-10-35-16-55 ~]$ yum update
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
You need to be root to perform this command.
[ec2-user@ip-10-35-16-55 ~]$ sudo !!
sudo yum update
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
....

!?String[?]

说明

执行上一个包含String的命令, 如果String后面紧跟着新行, 则后面的?可以省略

样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@ip-10-35-16-55 ~]# history |tail -10
1000 history |tail -10
1001 ps -ef
1002 ll /tmp
1003 systemctl status docker
1004 history |tail -5
1005 ps -ef
1006 history |tail -5
1007 ps -ef
1008 history |tail -5
1009 history |tail -10
[root@ip-10-35-16-55 ~]# !?status
systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
....

^string1^string2^

说明

执行上一个命令, 但是使用string2替换string1

样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@ip-10-35-16-55 ~]# cat /etc/os-release
NAME="Amazon Linux"
VERSION="2"
ID="amzn"
ID_LIKE="centos rhel fedora"
VERSION_ID="2"
PRETTY_NAME="Amazon Linux 2"
ANSI_COLOR="0;33"
CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2"
HOME_URL="https://amazonlinux.com/"
[root@ip-10-35-16-55 ~]# ^cat^head -3^
head -3 /etc/os-release
NAME="Amazon Linux"
VERSION="2"
ID="amzn"

单词指示符 - Word Designators

单词指示符用于从事件中选择所需的单词。“:”将事件规范与单词指示符分隔开。如果单词指示符以“^”、“$”、“*”、“-”或“%”开头,则可以省略。单词从行首开始编号,第一个单词用0(零)表示。单词插入到当前行中,由单个空格分隔。

!!

说明

指定前面的命令。键入此命令时,前面的命令将全部重复。

样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[ec2-user@ip-10-35-16-55 ~]$ cat /etc/os-release
NAME="Amazon Linux"
VERSION="2"
ID="amzn"
ID_LIKE="centos rhel fedora"
VERSION_ID="2"
PRETTY_NAME="Amazon Linux 2"
ANSI_COLOR="0;33"
CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2"
HOME_URL="https://amazonlinux.com/"
[ec2-user@ip-10-35-16-55 ~]$ !!
cat /etc/os-release
NAME="Amazon Linux"
VERSION="2"
ID="amzn"
ID_LIKE="centos rhel fedora"
VERSION_ID="2"
PRETTY_NAME="Amazon Linux 2"
ANSI_COLOR="0;33"
CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2"
HOME_URL="https://amazonlinux.com/"
[ec2-user@ip-10-35-16-55 ~]$ ls
Anaconda3-2022.05-MacOSX-arm64.pkg nohup.out pycharm
[ec2-user@ip-10-35-16-55 ~]$ !!
ls
Anaconda3-2022.05-MacOSX-arm64.pkg nohup.out pycharm
[ec2-user@ip-10-35-16-55 ~]$

!!:$

说明

指定前面命令的最后一个参数。这可以缩短为!$。

样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[ec2-user@ip-10-35-16-55 ~]$ cat /etc/os-release
NAME="Amazon Linux"
VERSION="2"
ID="amzn"
ID_LIKE="centos rhel fedora"
VERSION_ID="2"
PRETTY_NAME="Amazon Linux 2"
ANSI_COLOR="0;33"
CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2"
HOME_URL="https://amazonlinux.com/"
[ec2-user@ip-10-35-16-55 ~]$ ls !!:$
ls /etc/os-release
/etc/os-release
[ec2-user@ip-10-35-16-55 ~]$ ls !$
ls /etc/os-release
/etc/os-release
[ec2-user@ip-10-35-16-55 ~]$

!fi:2

说明

指定最近命令的第二个参数,以字母fi开头。

样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@ip-10-35-16-55 ~]# docker logs adae
2022/08/25 01:37:10 Using config file: /.filebrowser.json
2022/08/25 01:37:10 Listening on [::]:80
2022/09/09 06:41:46 /api/renew: 401 10.11.17.86 <nil>
2022/09/13 07:53:28 Caught signal terminated: shutting down.
2022/09/13 07:53:28 accept tcp [::]:80: use of closed network connection
2022/09/13 07:53:40 Using config file: /.filebrowser.json
2022/09/13 07:53:40 Listening on [::]:80
2022/09/13 07:54:02 Caught signal terminated: shutting down.
2022/09/13 07:54:02 accept tcp [::]:80: use of closed network connection
2022/09/13 07:54:15 Using config file: /.filebrowser.json
2022/09/13 07:54:15 Listening on [::]:80
2022/09/22 01:42:21 /api/renew: 401 10.11.18.134 <nil>
2022/09/26 01:26:20 /api/renew: 401 10.11.18.17 <nil>
[root@ip-10-35-16-55 ~]# docker exec -it !docker:2 sh
docker exec -it adae sh
/ #

具体单词指示符

单词 说明
0(零) 第0个单词。对于大多数应用程序,这是命令名称。
n 第n个单词。
^ 第一个参数。
$ 最后一个参数。
% ?string?搜索最近的一个匹配结果,如果搜索字符串以作为单词一部分的字符开头。
x-y 字符范围,0-y缩写为-y
* 所有单词,除了第 0 个。 这是1-$的同义词。 如果事件中只有一个单词,则使用*不会报错; 在这种情况下返回空字符串。
x* x-$的缩写。
x- x-$的缩写,类似于x*,但省略了最后一个单词。如果缺少“x”,则默认为0。

如果提供的单词指示符没有事件规范,则使用前一个命令作为事件。

参考链接

command line - Understanding the exclamation mark (!) in bash - Unix & Linux Stack Exchange

History Interaction (Bash Reference Manual)

Event Designators (Bash Reference Manual)

Word Designators (Bash Reference Manual)

下面两个写的非常好, 推荐阅读 👍

15 Linux Bash History Expansion Examples You Should Know

15 Examples To Master Linux Command Line History