Bash基本语法
echo命令
echo
命令用于在终端输出文本或变量的值。它是一个非常常用的命令,通常用于调试脚本或显示信息。作用是在屏幕输出一行文本,可以将该命令的参数原样输出。
echo hello worldhello world
如果想要输出的是多行文本,即包括换行符。这时需要把多文本放在引号里面。
echo "<div class="swiper-container"> <div class="swiper-wrapper"> <div class="swiper-slide"><img src="./image/sku-13811216-01.png"></div> <div class="swiper-slide"><img src="./image/sku-13811216-02.png"></div> <div class="swiper-slide"><img src="./image/sku-13811216-03.png"></div> </div> <div class="swiper-pagination"></div></div>"
上面的例子中,echo可以原样输出多行文本。
-n 参数
默认情况下,echo
命令输出的文本末尾会有一个回车符号。-n
参数可以取消末尾的回车符号,使得下一个提示符号紧跟在输出内容的后面。
echo -n hello worldhello world$
echo a;echo bab
echo -n a;echo bab
例子中,-n
参数可以让2个echo
命令的输出连在一起,出现在同一行
-e 参数
-e
参数会解释引号(双引号和单引号)里面的特色字符(比如换行符\n)。如果不使用-e
参数,默认情况下,引号会让特殊字符变成普通字符。echo命令不解释它们,会原样输出
echo "Hello\nWorld"Hello\nWorld
# 双引号的情况echo -e "Hello\nWorld"HelloWorld
# 单引号的情况echo -e 'Hello\nWorld'HelloWorld
命令格式
命令行环境中,主要通过使用Shell命令。进行各种操作。Shell命令的格式如下:
command [ arg1 ... [ argN ]]
command
是具体的命令或者一个可执行的文件,arg1 ... argN
是传递给命令的参数,它们是可选的。
Bash单个命令一般都是一行,用户按下回车键,就开始执行。有效命令比较长,写成多行会有利于阅读和编辑,这时可以在每一行的结尾加上反斜杠, Bash会将下一行跟当前行放在一起解释。
echo foo bar
# 等同于echo foo \bar
空格
Bash使用空格(或者Tab键)区分不同的参数
command foot bar
命令中的,foot和bar之间有一个空格,所以Bash认为它们是两个参数。 如果参数之间有多个空格,Bash会自动忽略多余的空格。
echo this is a testthis is a test
分号
分号(;
)是命令的结束符号,使得一行可以放置多个命令,上一个命令执行结束后,再执行第二个命令。
clear;ls -l
例子中,Bash先执行clear
命令,执行完成后,再执行ls -l
命令。
注意,使用分号时,第二个命令总是接着第一个命令的执行,不管第一个命令执行是成功还是失败。
命令的组合符&&
和 ||
除了分号,Bash还提供了两个命令组合符号&&
和||
,允许更好地控制多个命令之间的继发关系。
Command1 && Command2
上述命令的含义是,如果命令Command1
执行成功,则继续执行Command2
命令。
Command1 || Command2
上面命令的含义是,如果命令Command1
命令运行失败,则继续运行Command2
命令。
下面是一些例子:
cat text.txt; ls -l
只要cat
命令执行结束,不管成功或者失败,都会继续执行ls -l
命令
cat text.txt && ls -l
只要cat
命令执行成功,才会继续执行ls -l
命令,如果cat命令执行失败(比如不存在文件text.txt),那么ls命令就不会执行。
cat text.txt || ls -l
只有cat命令执行失败(比如不存在text.txt),才会继续执行ls -l
命令,如果cat命令执行成功,ls命令就不会执行。
type命令
Bash本身内置了很多命令,同时也可以执行外部程序。怎么知道一个命令是内置命令还是外部程序呢?
type
命令用来判断命令的来源
type echoecho is a shell builtin
type lsls is hashed (/bin/ls)
上面代码中,type
命令告诉我们,echo是内部命令,ls是外部程序(/bin/ls)
type
命令本身也是内置的命令。
如果要查看一个命令的所有定义,可以使用type命令的-a
参数
type -a echoecho is a shell builtinecho is /bin/echo
echo命令即是内置命令,也有对应的外部程序。
type命令的-t
参数,可以返回一个命令的类型:别名(alias),关键词(keyword),函数(function),内置命令(builtin)和文件(file)
type -t bashfile
type -t ifkeyword
bash是文件,if是关键词。
快捷键
Ctrl + L
:清除屏幕并将当前行移动到页面顶部Ctrl + C
:中止当前正在执行的命令Shift + PageUp
:向上滚动Shift + PageDown
:向下滚动Ctrl + U
:从光标位置删除到行首Ctrl + K
:从光标位置删除到行尾Ctrl + W
:删除光标位置前一个单词Ctrl + D
:关闭Shell会话
除了上面的快捷键,Bash 还具有自动补全功能。命令输入到一半的时候, 可以按下 Tab 键,Bash 会自动完成剩下的部分。比如,输入tou,然后按一下 Tab 键,Bash 会自动补上ch。
除了命令的自动补全,Bash 还支持路径的自动补全。有时,需要输入很长的路径, 这时只需要输入前面的部分,然后按下 Tab 键,就会自动补全后面的部分。 如果有多个可能的选择,按两次 Tab 键,Bash 会显示所有选项,让你选择
引号和转义
Bash只有一种数据类,就是字符串。不管用户输入什么数据,Bash都视为字符串。字符串相关的引号和转义,对Bash来说非常重要。
转义
某些特殊字符在Bash里面有特殊的含义,比如$
、&
、*
、\
等
echo $date
上面的echo输出$date
不会有任何结果,因为$
是一个特殊字符。如果想要原样输出这些字符,就必须在它们前面加上反斜杠,使其变成普通的字符。这就叫做转义。
echo \$date
$date
上述的命令中,只有在特殊字符$
前面加上了反斜杠,Bash才会将其视为普通字符。输出结果是$date
。
反斜杠本身也是特殊字符,如果想要原样输出反斜杠,就需要对其自身转义,连续使用两个反斜杠即可。(\\
)
echo \\
反斜杠除了用于转义,还可以表示一些不可打印的字符.
\a
\b
: 退格\n
: 换行\r
: 回车\t
: 制表符
如果想要在这些命令行中使用这些不可打印的字符,可以把它们放到引号里面,然后使用echo命令的-e
参数.
echo a\tbalt
echo -e "a\tb"a b
上述例子中,命令行直接输出不可打印字符\t
,Bash不能正常解释.必须把它们放在引号之中,然后使用echo命令的-e
参数.
换行符是一个特殊的字符,表示命令的结束,Bash收到这个字符后,就会对其输入的命令进行解释执行.换行符前面加上反斜杠转义,就使得换行符变成普通字符,Bash会将其当做长度为0的空字符处理,从而可以将一行命令写成多行.
mv \/path/to/foo \/path/to/bar
# 等同于mv /path/to/foo /path/to/bar
例子中,如果一条命令过长,就可以在行尾使用反斜杠,将其改写成多行.这是常见的多行命令的写法.
单引号
Bash允许字符串放在单引号或双引号之中,加以引用.
单引号用于保留字符的字面含义,比如各种特殊字符在单引号里,都会变成普通字符.比如*
$
\
等。
echo '*'*
echo '$((2+2))'$((2+2))
echo '$(echo foo)'$(echo foo)
上面命令中,单引号使得 Bash 扩展、变量引用、算术运算和子命令,都失效了。如果不使用单引号,它们都会被 Bash 自动扩展。
由于反斜杠在单引号里面变成了普通字符,所以如果单引号之中,还要使用单引号,不能使用转义。合理的方法是在双引号中使用单引号
echo "it's a test"
双引号
双引号比单引号更宽松,大部分特殊字符在双引号里面都会失去特殊的含义,变成普通字符。
echo "*"*
通配符*
是一个特殊字符,放在双引号之中,就变成了普通字符,会原样输出。这一点需要特别留意,这意味着双引号里面不会进行文件名扩展。
但是,$
反引号` 和反斜杠\
这三个字符在双引号之中,依然有特殊含义,会被Bash自动扩展。
echo "$SHELL"/bin/zsh
echo "`date`"Sat Apr 12 11:41:11 CST 2025echo "`date`"
例子中,$
和反引号` 在栓引号中,都保持特殊含义。$符号用来引用变量,反引号则执行子命令。
echo "I'd say: \"hello.\""I'd say: "hello."
echo "\\"\
反斜杠在双引号之中保持特殊含义用来转义。索引可以使用反斜杠,在双引号之中插入双引号或者插入反斜杠本身。
换行符在双引号之中会失去特殊含义,Bash不在将其解释为命令的结束,只是作为普通的换行符。所以可以利用双引号,在命令输入多行文本。
echo "hello> world"helloworld
Bash在正常情况下会将换行符解释为命令的结束,但是换行符在双引号之中就失去了特殊作用,只用来换行,所以可以输入多行文本。echo命令会将换行符原样输出,显示的时候正常解释为换行。
双引号的另一个常见的使用场景是文件名包含空格。这时候就必须使用双引号或(单引号),将文件名放在里面。
ls "tow words.txt"
tow words.txt
是一个包含空格的文件名,如果不放在双引号里面,就会被Bash当做两个文件。
双引号会原样保存多余的空格。
echo "this is a test"this is a test
双引号还有一个作用,就是保存原始命令的输出格式。
echo $(cal)April 2025 Su Mo Tu We Th Fr Sa 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 28 29 30
echo "$(cal)" April 2025Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 1213 14 15 16 17 18 1920 21 22 23 24 25 2627 28 29 30
如果$(cal)
不放在双引号之中,echo 就会将所有结果以单行输出。丢弃了所有原有的格式。
Here文档
Here文档是一种输入多行字符串的方法,格式如下:
<< EOFtextEOF
它的格式分成开始标记<< EOF
和结束标记 EOF
。开始标记是两个小于号 + Here 文档的名称,名称可以随意取,后面必须是一个换行符;结束标记是单独一行顶格写的Here文档名称,如果不是顶格,结束标记不起作用。两者之间就是多行字符串的内容。
cat << EOF> <html>> <head>> <title>> The title of your page> </title>> </head>>> <body>> Your page content goes here.> </body>> </html>> EOF<html><head> <title> The title of your page </title></head>
<body> Your page content goes here.</body></html>
Here文档内部会发生变量替换,同时支持反斜杠转义,但是部支持通配符扩展,双引号和单引号也失去语法作用,变成了普通字符。
cat << EOF> $foo> "$foo"> '$foo'> EOFhello world"hello world"'hello world'
变量$foo
发生了替换,但是双引号和单引号都原样输出了。表明它们已经失去了引用的功能。
如果不希望发生变量替换,可以把Here文档的开始标记放在单引号之中。
cat << 'EOF'> $foo> "$foo"> '$foo'> EOF$foo"$foo"'$foo'
上面的例子中,Here文档的开始标记EOF
放在单引号之中,导致变量替换失效了。
Here文档的本质是重定向,它将字符串重定向输出给某个命令,相当于包含了echo
命令。
command << EOF> string> EOF
# 等同于
echo string | command
此外,Here文档也不能作为变量的值,只能用于命令的参数。
Here字符串
Here文档还有一个变体,叫Here字符串(Here string),使用三个小于号<<<
表示。
<<< string
它的作用是将字符串通过标准输入,传递给命令。
有些命令直接接受给定的参数,与通过标准输入接受参数,结果是不一样的。所以才有了这个语法,使得将字符串通过标准输入传递命令更方便,比如cat
命令只接受标准输入传入的字符串。
cat <<< 'hi there'hi there
# 等同于
echo 'hi there' | cat
上面的第一种语法使用了Here字符串,要比第二种语法抗上去语义更好,也更简洁。
md5sum <<< 'ddd'
# 等同于echo 'ddd' | md5sum
上面例子中,md5sum
命令只能接受标准输入作为参数,不能直接将字符串放在命令后面,会被当作文件名。即:md5sum ddd
里面的ddd
会被解释成文件名。这时就可以用Here字符串,将字符串传给md5sum
命令。