'!'
Linux 中的符号或运算符可用作逻辑否定运算符,也可通过调整从历史记录中获取命令,或通过修改运行先前运行的命令。以下所有命令均已在 bash Shell 中明确检查。虽然我没有检查过,但其中大部分不会在其他 shell 中运行。
1. 命令编号运行历史记录中的命令
您可能不知道您可以从历史命令(已经 / 较早执行的命令)运行命令这一事实。要开始,首先通过运行 “history” 命令找到命令编号。
$ history
现在,在history的输出中,仅按照它出现的编号运行来自history的命令。假设运行出现在’history‘ 命令输出中编号为1551的命令。
$ !1551
并且,它运行在编号1551中列出的命令。这种检索已执行命令的方法非常有用,特别是在那些很长的命令的情况下。您只需要使用**!**来调用它。
2. 将先前执行的命令作为倒数第二个命令、倒数第 7 个命令等运行
你可以运行那些你之前运行过的命令,它们的运行顺序是最后一个运行命令将表示为**-1**,倒数第二个为**-2**,倒数第七个为**-7**,……。
首先运行history命令以获取上次执行命令的列表。有必要运行history命令,这样您就可以确保没有类似的命令rm command > file
和其他命令,只是为了确保您不会意外运行任何危险的命令。然后检查第六个最后一个命令,八个最后一个命令和第十个最后一个命令。
$ history
$ !-6
$ !-8
$ !-10
按数字运行上次执行的命令
3. 将我们运行的最后一个命令的参数传递给新命令,无需重新输入
我需要列出目录 “/home/$USER/Binary/firefox” 的内容
$ ls /home/$USER/Binary/firefox
然后我意识到我应该触发 “ls -l” 以查看哪个文件在那里可执行?所以我应该再次输入整个命令!不,我不需要。我只需要将这个新命令的最后一个参数作为:
$ ls -l !$
这里!$
将携带在最后一个命令中传递给这个新命令的参数
将上次执行命令的参数传递给新命令
4. 如何使用 (!) 处理两个或多个参数
假设我在桌面上创建了一个文本文件1.txt
$ touch /home/avi/Desktop/1.txt
然后使用cp命令在任一侧使用完整路径将其复制到 “/home/avi/Downloads”
$ cp /home/avi/Desktop/1.txt /home/avi/downloads
现在我们已经使用cp命令传递了两个参数。第一个是 “/home/avi/Desktop/1.txt”,第二个是 “/home/avi/Downloads”,让我们以不同的方式处理它们,只需执行echo [arguments]
以不同方式打印两个参数
$ echo "1st Argument is : !^"
$ echo "2nd Argument is : !cp:2"
注意第一个参数可以打印为“!^”
,其余参数可以通过执行“![Name_of_Command]:[Number_of_argument]”
.
在上面的例子中,第一个命令是 “cp”,第二个参数需要打印。因此“!cp:2”
,如果任何命令说xyz使用 5 个参数运行并且您需要获得第 4 个参数,您可以使用“!xyz:4”
,并根据需要使用它。所有参数都可以通过 访问“!*”
。
5. 根据关键字执行最后一条命令我们可以根据关键字执行上次执行的命令。我们可以这样理解:
$ ls /home > /dev/null [Command 1]
$ ls -l /home/avi/Desktop > /dev/null [Command 2]
$ ls -la /home/avi/Downloads > /dev/null [Command 3]
$ ls -lA /usr/bin > /dev/null [Command 4]
在这里,我们使用了相同的命令**(ls),但使用了不同的开关和不同的文件夹。此外,我们已将每个命令的输出发送到 “/dev/null**”,因为我们不会处理命令的输出,控制台也保持干净。
现在根据关键字执行上次运行命令
$ ! ls [Command 1]
$ ! ls -l [Command 2]
$ ! ls -la [Command 3]
$ ! ls -lA [Command 4]
检查输出,您会惊讶地发现您只是通过ls
关键字运行已执行的命令
根据关键字运行命令
6. 神奇的!!
您可以使用(!!)
.它将在当前命令中使用 alter/tweak 调用最后一个运行命令。给你看场景
最后一天我运行了一个单行脚本来获取我的私有 IP,所以我运行
$ ip addr show | grep inet | grep -v 'inet6'| grep -v '127.0.0.1' | awk '{print $2}' | cut -f1 -d/
然后我突然发现我需要将上面脚本的输出重定向到一个文件ip.txt,那我该怎么办?我应该再次重新输入整个命令并将输出重定向到文件吗?那么一个简单的解决方案是使用UP
导航键并添加'> ip.txt'
将输出重定向到文件
$ ip addr show | grep inet | grep -v 'inet6'| grep -v '127.0.0.1' | awk '{print $2}' | cut -f1 -d/ > ip.txt
UP
键可以快速找到历史命令。现在考虑以下条件,下次我在单行脚本下运行时
$ ifconfig | grep "inet addr:" | awk '{print $2}' | grep -v '127.0.0.1' | cut -f2 -d:
一旦我运行脚本,bash 提示符就会返回一个错误消息“bash: ifconfig: command not found”
,我不难猜测我以用户身份运行此命令,而它应该以 root 身份运行
那么有什么解决办法呢?很难登录到 root 然后再次键入整个命令!此外,上一个示例中的(向上导航键)在这里也没有出现。所以?我们需要“!!”
不带引号调用,这将调用该用户的最后一个命令
$ su -c !! root
这里su是切换用户,也就是 root,-c
以用户身份运行特定的命令,最重要的部分!!
将被命令替换,最后运行的命令将在这里替换。是的!您需要提供 root 密码。
!!
主要在以下场景中使用
当我以普通用户身份运行apt-get命令时,我通常会收到一个错误,说您无权执行
$ apt-get upgrade && apt-get dist-upgrade
Opps 错误… 不要担心执行以下命令以使其成功
$ su -c !!
$ service apache2 start
or
$ /etc/init.d/apache2 start
or
$ systemctl start apache2
OOPS 用户无权执行此类任务,所以我运行
$ su -c 'service apache2 start'
or
$ su -c '/etc/init.d/apache2 start'
or
$ su -c 'systemctl start apache2'
7. 运行影响除 ![FILE_NAME] 之外的所有文件的命令
该!
(逻辑 NOT)可以用来运行所有命令的文件 / 文件扩展名,除了后面'!'
7.1 从目录中删除所有文件,但名称为2.txt的文件除外
$ rm !(2.txt)
7.2 从文件夹中删除所有文件类型,除了扩展名为 “pdf”的文件类型
8. 检查一个目录(比如 / home/avi/Tecmint)是否存在?printf 如果所述目录存在与否
在这里,我们将使用'! -d'
来验证目录是否存在,然后使用逻辑 AND 运算符(&&)
来打印该目录不存在,然后使用逻辑 OR 运算符(||)
来打印目录是否存在
$ $ rm !(*.pdf)
逻辑是,当输出[ ! -d /home/rumenz ]
为0 时,它将执行超出 Logical 的内容**,否则它将转到 Logical OR(||)
并执行超出 LogicalOR 的内容**
$ [ ! -d /home/rumenz ] && printf '\nno such /home/rumenz directory exist\n' || printf '\n/home/rumenz directory exist\n'
9. 检查目录是否存在?如果没有退出命令。与上述条件类似,但这里如果所需目录不存在,它将退出命令
$ [ ! -d /home/rumenz ] && exit
10. 如果它不存在,则在您的主目录中创建一个目录(比如 rumenz)。脚本语言中的一种通用实现,如果所需目录不存在,它将创建一个
[ ! -d /home/rumenz ] && mkdir /home/rumenz