本章主要介绍如何在实际场景中可能经常使用到的,及易混淆的一些用法(Basic Construction/Varitions)。关于基本语法,将会在下方板栗中顺带提及,不在单独章节中做太详细介绍,可先在下方推荐链接中学习。
推荐基础指南: https://www.tutorialkart.com/bash-shell-scripting/bash-tutorial/
深入研究 (Advanced Bash-Scripting Guide): https://tldp.org/LDP/abs/html/bash2.html
还需对下方内容有所了解:
- 常见的Shell类型及其区别:sh(Bourne Shell),Korn Shell等
- Shell的版本:不同版本所兼容的语法也略有不同
- 运行脚本时所处的OS及其版本
- 与一般编程语言(高级语言)的细微语法差别,例如空格,双引号等
- 脚本的执行权限
- 需处理的文件,及其所在文件夹的权限
0. 涉及的入门语法 Syntax For Quick Start
- Variable & Arithmetic 变量(类型)与赋值:数组,算术操作符
- Loop 循环 :for,while,until
- Conditional Statements 条件判断:if-elseif-else,case
- 字符串处理
- 函数
- 文件操作
关于基础语法的花样用法,会在下方板栗里一一呈现 (统一注释上: # 0.Syntax - )
1. 编译器 Compiler
Q1: 在脚本的开头,我们经常看到的 #!/bin/sh
与 #!/bin/bash
有什么区别?
Tip: 相当于问sh跟bash的区别。sh相当于没有开启POSIX模式的bash。
#!/bin/sh
相当于 #!/bin/bash --posix
可自行了解:
- POSIX = Portable Operating System Interface,可移植操作系统接口 (关于应用程序在不同OS间的兼容性的标准)
- 有接触过容器技术Docker的朋友结合POSIX做个深入了解。
根据OS支持的Shell脚本语言,选择对应的编译器。下面板栗的编译器为Korn Shell。
#!
意为指定该段脚本采用的shell编译器,可通过 cat /etc/shells 查看系统支持的shell格式
sh
是UNIX的标准编译器,但与用户的交互性不如csh、ksh等(但编译性又能不如sh)bash
是Linux的标准编译器,向后兼容sh,且集合sh、ksh等的优点
2. 输入
2.1 命令行参数
# 输入 --------------------------------------
# $ ./test.sh val1 val2 -> 输入的命令行参数: val1 val2
echo "运行脚本时,在命令行输入的参数个数 = "$#
echo "传递给脚本或函数的第一个参数 = "$1
echo "不存在的参数会输出一个空号.$3."
2.1 交互式输入
echo "=============== 结合输入:交互式 - Start ==============="
echo "Say 'Y' to continue ..." #Read User Input
read said
echo "what did i say -> " $said
echo "Tell me ur name to continue ..."# Read User Input
read firstname lastname
echo "ur firstname is $firstname, lastname is $lastname."
echo "=============== 交互式 - End ==============="
3. 输出
在Linux下运行指定位置的脚本
3.1 输出到控制台
# 输出到控制台 -------------------------------
echo "=============== 对特殊字符的转义 - 在输出时,使用optional的参数进行控制 ==============="
echo "Hi my shell !"
echo -e "当输出内容包含特殊字符(换行符)并想实现时 -e \n my shell"
echo -E "当输出内容包含特殊字符(换行符)但不想实现时 -E \n my shell"
echo "=============== 对特殊字符的转义 - 在定义时,使用两个反斜杠 ==============="
var1=`echo \$HOME` #使用一个反斜杠无法完成对$符的转义
var2=`echo \\$HOME`
var3=$(echo \$HOME) #注意这里可不用空格
echo $var1 #/root
echo $var2 # $HOME
echo $var3 # $HOME
3.2 输出到指定文件
print1="输出到指定文件"
echo >> ./test.txt # 输出到当前文件夹下的test.txt文件下,如果文件原本不存在,会自动创建
4. 算术运算符 Arithmetic Operators
There are 11 arithmetic operators supported by Bash Shell.
另外会涉及到下方三个用法
$(( ))
Double parenthesis could be used for arithmetic expansion.let
let command is used to carry out arithmetic operations 进行算术运算, 变量可以不加$
直接使用.expr
Arithmetic expansion could be done using 反引号 backticks and expr (all purpose expression evaluator).
总结:
$(( )) | let | expr | |
---|---|---|---|
算术运算符+ | √ | √ 需结合$(( )) | √ |
算术赋值运算符+= | √ 可不带$ | √ 不需结合$(( )) ,直接双引号囊括 | X |
# (( ))
x=1
y=2
echo "(( )) 算术时 - 变量不带$: " $(( x + y )) # addition
echo "(( )) 算术时 - 变量带$: " $(( $x + $y )) # also valid
(( x += 4 )) # increment variable by constant
echo "(( )) 算术赋值时 - 不用带$:" $x
echo -e "\n"
a=1
b=2
c=0
let "c = $(( a + b ))" # addition
let c=$((a+b)) # also valid without double quotes when no spaces in expression
echo "let 算术时 - 也不用双引号,空格也可以省略:" $c
let "a += 4" # increment variable by constant
echo "let 算术赋值时 - 必须要用双引号:" $a
i=`expr $a + $b`
echo -e "\n expr 仅适合于算术:"$i
5. 需注意语法
5.1 花括号的使用
echo "使用变量时,花括号的作用"
A="test"
AB="123"
echo $AB # 输出AB的值:123
echo ${A}B # 输出A的值且拼接上B:testB
5.2 双引号的使用
# $@与$*的区别:双引号的使用
for item1 in $@; do
echo "没有双引号时的@ 输出每个参数 = "${item1}
done
for item1 in $*; do
echo "没有双引号时的* 输出每个参数 = "${item1}
done
for item1 in "$@"; do
echo "有双引号时的@ 会将各个参数作为个体分开 = "${item1}
done
for item1 in "$*"; do
echo "有双引号时的* 会将所有的参数作为一个整体 = "${item1}
done
5.3 空格的使用
A. 不可留空格
- 定义变量时, =号的两边
val=10 - 取变量值的符号’$'和后边的变量或括号
B. 留空格
- 条件测试/判断语句 [ 符号的两边
val="123test"
if [ ${val} = 2 ]; then
echo "val的值为2."
elif [[ ${val} =~ .*test$ ]]; then
echo "val的值为test结尾的字符串."
else
echo "val的值未知"
fi
- 命令和其后的参数或对象之间一定要有空格
if [ -f "./test/demo.txt"] # 判断是否为文件
- 操作符之间要用空格分开
6. 字符串处理
截取
拼接