如果您想在 Linux、macOS 或其他类 UNIX 系统上精通 Bash shell,特殊字符(如 ~、*、| 和 >)至关重要。我们将帮助您解开这些神秘的 Linux 命令序列,成为象形文字的英雄。
Bash shell 以两种不同的方式处理一组字符。当您在 shell 中键入它们时,它们充当指令或命令并告诉 shell 执行特定功能。将它们视为单字符命令。
有时,您只想打印一个字符,而不需要它充当魔法符号。有一种方法可以使用角色来代表它自己而不是它的特殊功能。
我们将向您展示哪些字符是“特殊”或“元”字符,以及如何在功能上和字面上使用它们。
波浪号 (~) 是您的主目录的简写。这意味着您不必在命令中键入主目录的完整路径。无论您在文件系统中的哪个位置,都可以使用此命令转到您的主目录:
cd ~
您还可以将此命令与相对路径一起使用。例如,如果您位于文件系统中不在您的主文件夹下的某个位置,并且想要更改到您的 work
目录中的 archive
目录,请使用波浪号来执行它:
cd ~/work/archive
句点 (.) 表示当前目录。如果将 -a
(全部)选项与 ls
一起使用,您会在目录列表中看到它。
ls -a
您还可以在命令中使用句点来表示当前目录的路径。例如,如果你想从当前目录运行一个脚本,你可以这样调用它:
./script.sh
这告诉 Bash 在当前目录中查找 script.sh
文件。这样,它就不会在您的路径中搜索目录来匹配可执行文件或脚本。
双句点或“双点”(..) 代表当前目录的父目录。您可以使用它在目录树中向上移动一个级别。
cd ..
您还可以将此命令与相对路径一起使用——例如,如果您想要在目录树中上升一个级别,然后进入该级别的另一个目录。
您还可以使用此技术快速移动到目录树中与当前目录处于同一级别的目录。你跳上一层,然后跳下一层进入不同的目录。
cd ../gc_help
您可以使用正斜杠 (/)(通常简称为斜杠)来分隔路径名中的目录。
ls ~/work/archive
一个正斜杠表示可能的最短目录路径。因为 Linux 目录树中的所有内容都从根目录开始,您可以使用此命令快速移动到根目录:
cd /
大多数情况下,您使用井号或数字符号 (#) 来告诉 shell 以下是注释,它不应对其执行操作。您可以在 shell 脚本中使用它,也可以在命令行中使用它,但用处不大。
# This will be ignored by the Bash shell
但是,它并没有真正被忽略,因为它已添加到您的命令历史记录中。
您还可以使用散列来修剪字符串变量并从开头删除一些文本。此命令创建一个名为 this_string
的字符串变量。
在此示例中,我们分配文本“Dave Geek!”到变量。
this_string="Dave Geek!"
此命令使用 echo
将“How-To”字样打印到终端窗口。它通过参数扩展检索存储在字符串变量中的值。因为我们附加了散列和文本“Dave”,所以它会在将字符串传递给 echo
之前删除该部分字符串。
echo How-To ${this_string#Dave}
这不会改变存储在字符串变量中的值;它只会影响发送到 echo
的内容。我们可以使用 echo
再次打印字符串变量的值并检查:
echo $this_string
Bash shell 支持三种通配符,其中一种是问号 (?)。您可以使用通配符替换文件名模板中的字符。包含通配符的文件名形成一个匹配一系列文件名的模板,而不仅仅是一个。
问号通配符代表恰好一个字符。考虑以下文件名模板:
ls badge?.txt
这翻译为“列出名称以‘徽章’开头且后跟文件扩展名之前的任何单个字符的任何文件。”
它匹配以下文件。请注意,有些在文件名的“标志”部分后有数字,有些有字母。问号通配符将同时匹配字母和数字。
但是,该文件名模板与“badge.txt”不匹配,因为文件名在“badge”和文件扩展名之间没有单个字符。问号通配符必须匹配文件名中的相应字符。
您还可以使用问号查找文件名中具有特定字符数的所有文件。这列出了文件名中恰好包含五个字符的所有文本文件:
ls ?????.txt
您可以使用星号 (*) 通配符代表任何字符序列,包括无字符。考虑以下文件名模板:
ls badge*
这符合以下所有条件:
它匹配“badge.txt”,因为通配符代表任何字符序列或不代表任何字符。
此命令匹配所有名为“source”的文件,无论文件扩展名如何。
ls source.*
如上所述,您使用问号表示任何单个字符,使用星号表示任何字符序列(包括无字符)。
您可以使用方括号 ( [] ) 及其包含的字符构成通配符。文件名中的相关字符必须与通配符集中的至少一个字符相匹配。
在此示例中,该命令转换为:“任何具有“.png”扩展名、文件名以“pipes_0”开头且下一个字符为 2、4 或 6 的文件。 ”
ls badge_0[246].txt
每个文件名模板可以使用多组括号:
ls badge_[01][789].txt
您还可以在字符集中包含范围。以下命令选择文件名中编号为 21 到 25 和 31 到 35 的文件。
ls badge_[23][1-5].txt
您可以在命令行中键入任意数量的命令,只要用分号 (;) 分隔每条命令即可。我们将在以下示例中执行此操作:
ls > count.txt; wc -l count.txt; rm count.txt
请注意,即使第一个命令失败,第二个命令也会运行,即使第二个失败,第三个命令也会运行,依此类推。
如果您想在一个命令失败时停止执行顺序,请使用双符号 (&&) 而不是分号:
cd ./doesntexist && cp ~/Documents/reports/* .
在终端窗口中键入命令并完成后,您将返回到命令提示符。通常,这只需要一两分钟。但是,如果您启动另一个应用程序,例如 gedit
,则在关闭该应用程序之前无法使用您的终端窗口。
但是,您可以将应用程序作为后台进程启动并继续使用终端窗口。为此,只需在命令行中添加一个符号:
gedit command_address.page &
Bash 向您显示启动的进程 ID,然后将您返回到命令行。然后您可以继续使用您的终端窗口。
许多 Linux 命令接受文件作为参数并从该文件中获取数据。这些命令中的大多数也可以从流中获取输入。要创建流,您可以使用左尖括号 ( < ),如以下示例所示,将文件重定向到命令中:
sort < words.txt
当命令将输入重定向到其中时,它的行为可能与从命名文件读取时的行为不同。
如果我们使用 wc
来计算文件中的单词、行和字符,它会打印值,然后是文件名。如果我们将文件的内容重定向到 wc
,它会打印相同的数值,但不知道数据来自哪个文件的名称。它无法打印文件名。
以下是如何使用 wc
的一些示例:
wc words.txt
wc < words.txt
您可以使用右尖括号 ( > ) 将命令的输出重定向(通常是文件);这是一个例子:
ls > files.txt
cat files.txt
如果您在 >
中使用数字(在我们的示例中为 2),则输出重定向也可以重定向错误消息。方法如下:
wc doesntexist.txt 2> errors.txt
cat errors.txt
“管道”将命令链接在一起。它获取一个命令的输出并将其作为输入提供给下一个命令。管道命令的数量(链的长度)是任意的。
在这里,我们将使用 cat
将 words.txt 文件的内容提供给 grep
,它会提取任何包含小写或大写“C”的行。 grep
然后会将这些行传递给 sort
。 sort
使用了 -r
(reverse) 选项,因此排序的结果将以相反的顺序出现。
我们输入了以下内容:
cat words.txt | grep [cC] | sort -r
感叹号 (!) 是一个逻辑运算符,表示 NOT。
该命令行中有两条命令:
[ ! -d ./backup ] && mkdir ./backup
&&
之后的文本。第一个命令使用 !
作为逻辑运算符。方括号表示将要进行测试。 -d
(目录)选项测试是否存在名为 backup 的目录。第二个命令创建目录。
因为双符号分隔两个命令,所以 Bash 只会在第一个成功时执行第二个。然而,这与我们需要的相反。如果“备份”目录测试成功,我们不需要创建它。如果对“备份”目录的测试失败,则不会执行第二条命令,也不会创建丢失的目录。
这就是逻辑运算符 !
的用武之地。它充当逻辑 NOT。因此,如果测试成功(即目录存在),!
会将其翻转为“不成功”,即失败。因此,第二个命令未激活。
如果目录测试失败(即目录不存在),!
会将响应更改为“NOT failure”,即成功。因此,创建缺失目录的命令被执行了。
那个小 !
可以在您需要时提供强大的功能!
要检查备份文件夹的状态,您可以使用 ls
命令以及 -l
(长列表)和 -d
(目录)选项, 如下所示:
ls -l -d backup
您还可以使用感叹号运行命令历史记录中的命令。 history
命令列出了您的命令历史记录,然后您可以使用 !
键入您希望重新运行的命令的编号来执行它,如下所示:
!24
下面重新运行前面的命令:
!!
在 Bash shell 中,您创建变量来保存值。有些变量,如环境变量,始终存在,您可以在打开终端窗口时随时访问它们。这些保存值,例如您的用户名、主目录和路径。
您可以使用 echo
来查看变量的值——只需在变量名称前加上美元符号 ($),如下所示:
echo $USER
echo $HOME
echo $PATH
要创建一个变量,您必须给它起一个名字并提供一个值供它保存。您不必必须使用美元符号来创建变量。仅在引用变量时添加 $
,例如以下示例:
ThisDistro=Ubuntu
MyNumber=2001
echo $ThisDistro
echo $MyNumber
在美元符号周围添加大括号 ({}) 并执行参数扩展以获取变量的值并允许对该值进行进一步的转换。
这将创建一个包含一串字符的变量,如下所示:
MyString=123456qwerty
使用以下命令将字符串回显到终端窗口:
echo ${MyString}
要返回从整个字符串的位置 6 开始的子字符串,请使用以下命令(有一个零偏移量,因此第一个位置为零):
echo ${myString:6}
如果要回显从位置零开始并包含接下来的六个字符的子字符串,请使用以下命令:
echo ${myString:0:6}
使用以下命令回显从位置 4 开始并包含接下来的四个字符的子字符串:
echo ${myString:4:4}
如果你想使用一个特殊字符作为文字(非特殊)字符,你必须告诉 Bash shell。这称为引用,可以通过三种方式进行。
如果将文本括在引号(“...”)中,这将阻止 Bash 对大多数特殊字符进行操作,它们只会打印出来。不过,一个值得注意的例外是美元符号 ($)。它仍然用作变量表达式的字符,因此您可以在输出中包含变量的值。
例如,此命令打印日期和时间:
echo "Today is $(date)"
如果您将文本用单引号 (‘...’) 括起来,如下所示,它会停止所有特殊字符的功能:
echo 'Today is $(date)'
您可以使用反斜杠 (\) 来防止后面的字符充当特殊字符。这称为“转义”角色;请参阅下面的示例:
echo "Today is \$(date)"
只需将特殊字符视为非常短的命令即可。如果您记住它们的用途,它可以极大地帮助您理解 Bash shell 和其他人的脚本。
Linux Commands | ||
Files | tar · pv · cat · tac · chmod · grep · diff · sed · ar · man · pushd · popd · fsck · testdisk · seq · fd · pandoc · cd · $PATH · awk · join · jq · fold · uniq · journalctl · tail · stat · ls · fstab · echo · less · chgrp · chown · rev · look · strings · type · rename · zip · unzip · mount · umount · install · fdisk · mkfs · rm · rmdir · rsync · df · gpg · vi · nano · mkdir · du · ln · patch · convert · rclone · shred · srm · scp · gzip · chattr · cut · find · umask · wc | |
Processes | alias · screen · top · nice · renice · progress · strace · systemd · tmux · chsh · history · at · batch · free · which · dmesg · chfn · usermod · ps · chroot · xargs · tty · pinky · lsof · vmstat · timeout · wall · yes · kill · sleep · sudo · su · time · groupadd · usermod · groups · lshw · shutdown · reboot · halt · poweroff · passwd · lscpu · crontab · date · bg · fg · pidof · nohup · pmap | |
Networking | netstat · ping · traceroute · ip · ss · whois · fail2ban · bmon · dig · finger · nmap · ftp · curl · wget · who · whoami · w · iptables · ssh-keygen · ufw · arping · firewalld |
RELATED: Best Linux Laptops for Developers and Enthusiasts