在 Linux 命令中使用 (!) 运算符的 8 种神秘方法
Linux 中的 '!'
符号或运算符可以用作逻辑否定运算符,也可以通过调整从历史记录中获取命令,或者通过修改运行以前执行的命令。
以下大多数使用 '!'
符号的 Linux 命令在不同的 shell 中可能会有所不同。虽然我提供的示例通常在 bash shell 中使用,但其他一些 Linux shell 可能有不同的实现,或者可能根本不支持“!”符号的某些用法。
让我们深入了解 '!'
符号或运算符在 Linux 命令中的惊人而神秘的用法。
1. 使用命令编号运行历史命令
您可能不知道您可以从历史命令(已经/之前执行的命令)运行命令。首先,通过运行“history”命令查找命令编号。
history
要按命令编号运行历史记录中的命令,您可以使用 '!'
符号,后跟命令编号,如下所示。
!1551
当您执行上述命令时,它将运行历史记录中第 1551 行的顶部命令。
请注意,实际命令编号可能会根据您的命令历史记录而有所不同。您可以使用历史命令查看命令列表及其行号。
2. 在 Linux 中运行之前执行过的命令
您可以按照运行顺序运行之前运行过的命令,最后运行的命令将表示为 -1,倒数第二个表示为 -2,倒数第七个表示为-7,等等。
例如,如果您想重新运行前 6、8 或 10 个命令执行的命令,则可以使用 !-n
,其中 n
是命令数回你想参考。
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. 在 Linux 中重复上次执行的命令
您可以使用 (!!)
运算符运行/更改上次执行的命令,这是一种速记符号,允许您引用命令行中执行的上一个命令。
例如,最后一天我运行了一个单行脚本来查找 Linux 计算机的 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 find”,我不难猜测我以用户身份运行此命令,其中它应该以 root 身份运行。
那么解决办法是什么呢?登录 root 然后再次输入整个命令是很困难的!另外,上一个示例中的(向上导航键)在这里也没有起到作用。所以?我们需要调用“!! ”
不带引号,这将调用该用户的最后一个命令。
su -c “!!” root
这里su是切换用户,即root,-c
是以用户身份运行指定的命令,最重要的部分!!
将被命令替换,并且最后运行的命令将被替换在这里。是的!您需要提供 root 密码。
7.使用“!”运算符删除除一个文件之外的文件
在 Linux 中,!
运算符(称为“bang”运算符)用于历史记录扩展,允许您引用命令历史记录中的先前命令并执行各种操作跟他们。
要从目录中删除除特定文件 (important_file.txt) 之外的所有文件,您可以使用带有 !
运算符的 rm 命令,如下所示。
rm !(important_file.txt)
从文件夹中删除除扩展名为“.pdf
”的文件类型之外的所有文件类型。
$ rm !(*.pdf)
8. 检查Linux中是否存在目录
这里我们将使用 '! -d'
验证目录是否存在或不存在,后跟逻辑 AND 运算符 (&&)
打印该目录不存在,逻辑 OR 运算符 (||)
打印目录是否存在。
逻辑是,当 [ ! -d /home/avi/Tecmint ]
是 0,它将执行逻辑 AND 之外的内容,否则它将转到逻辑 OR (| |)
并执行逻辑OR之外的内容。
[ ! -d /home/avi/Tecmint ] && printf '\nno such /home/avi/Tecmint directory exist\n' || printf '\n/home/avi/Tecmint directory exist\n'
与上面的情况类似,但这里如果所需的目录不存在,则会退出命令。
[ ! -d /home/avi/Tecmint ] && exit
脚本语言的一般实现,如果所需的目录不存在,它将创建一个。
[ ! -d /home/avi/Tecmint ] && mkdir /home/avi/Tecmint
目前为止就这样了。如果您知道或遇到任何值得了解的 '!'
用法,您可以在反馈中向我们提供您的建议。保持联系!