计算机工具基础(三)——Shell语法基础
Shell语法基础
MIT《Missing in CS Class(2020)》:Class 2笔记
注:若无特殊说明,本文中带有[]的部分均为可选参数。
脚本文件
- 脚本语言为解释执行,其运行需有解释器,如Python。
- Shell是一种脚本语言。其文件扩展名并不固定,随其解释器决定其扩展名。一般情况下为
.sh。 - 脚本文件的首行一般为
#! shell_name,符号#!被称为shebang,其规定该脚本以何种Shell解释器执行。一般采用env(/usr/bin/env)程序,到$PATH中查找某种解释器在何位置,如#!/usr/bin/env shell - 若同一行有多条命令,用
;分隔 - 执行脚本:分为子Shell执行与当前Shell执行。若为子Shell执行,在不使用
export的情形下,脚本中定义的各种变量、函数、环境都不会被带回当前Shell;若为当前Shell执行则反之,可在后续命令中调用脚本中定义的变量、函数等内容。./script_name.sh:仅当该脚本有可执行权限(x)时,根据shebang中规定的解释器,创建一个独立子Shell以执行该脚本shell_name ./script_name.sh:无论该脚本是否有可执行权限,忽略shebang,以shell_name创建一个独立子Shell以执行该脚本source ./script_name.sh或. ./script_name.sh:无论该脚本是否有可执行权限,忽略shebang,直接在当前Shell中执行该脚本,相当于将脚本中进行的修改注入到当前Shell。
变量
-
变量赋值:Shell与其他多数脚本语言一致,变量无需定义,直接赋值即可。右值可为数字、字符串、其他变量、数组、命令替换等。
name=value
注意赋值中各符号间不能有任何空格。 -
变量可被重新赋值使用。
-
变量使用:
$name -
删除变量:
unset name -
输出:
-
echo:如echo $a -
格式化输出:
printf format_string [arg_list],与C中相同
-
-
Shell定义了一些保留变量:
$0:脚本名$1-$9:脚本执行的第 \(i\) 项参数。类似于C中main函数的形参argv[]$@:所有参数$#:参数数量。类似于C中main函数的形参argc$$:当前脚本的PID(进程识别码)$?:上条程序的返回值。!!:上条包含所有参数的完整命令。如执行命令后被返回Permission Denied,使用sudo !!即可重新提升执行$_:上条命令的最后一项参数。如:mkdir 1,cd $_
数组、字符串
-
Shell只支持一维数组,所有
value都会被视为字符串处理-
初始化:
array_name=(value1,value2,...)。 -
赋值:
array_name[index]=value -
随机访问:
${name[index]}。特别的,idx为@时,代表取数组中所有元素。
-
-
关系数组:相当于Python中的
dic(字典)、C++中的map。与普通数组不同,关系数组必须声明后才能使用。-
声明:
declare -A array_name -
初始化:
declare -A array_name=(["key1"]="value1" ["key2"]="value2" ...),其中key必须唯一。 -
赋值:
array_name["key"]="value"
-
-
字符串:
- 单引号
‘包围的字符串:被视为字符串字面常量,所有内容将被原样存储,变量也不会被替换。如echo '$a':输出$a - 双引号
“包围的字符串:正常替换变量。如echo "$a":输出:b - 字符串长度:
${#name}
- 单引号
命令替换、进程替换
-
命令替换:
$(command):command命令的stdout替换$(command)本身。如:today=$(date) #将输出赋值给变量 echo "$today"for i in $(ls) ; do #遍历文件 echo "$i" donecd $(ls) -
进程替换:
-
输出重定向:
(command),将command的stdout写入临时文件中,可作为其他命令的文件读入。例:diff (ls dir1) (ls dir2) -
输入重定向:
(command),将其他命令的stdout写入临时文件中,由command读取。效果等价于管道符|
-
流程控制
选择结构
if…fi
注意Shell中的分支不可为空,若不需要就不要写对应的分支。注意在每个condition后都需加then
-
单分支结构:
if then ... fiif condition ; then command fi -
双分支结构:
if then ... else ... fiif condition ; then command else command fi -
多分支结构:
if then ... elif then ... else ... fiif condition ; then command elif condition ; then command else command fi
condition为布尔表达式时的两种表示形式:
[bool_expression]:-eq:判断两个数字是否相等;-ne:判断两个数字是否不相等;-lt:判断数字是否小于;-le:判断数字是否小于等于;-gt:判断数字是否大于;-ge:判断数字是否大于等于。((bool_expression)):算术专用的布尔表达式,直接使用关系运算符即可。
case...esac
case variable in
pattern)
command
;;
[
*) #相当于default
command
;;
]
esac
类似于C中的switch,顺次进行匹配。case...esac并没有原生的default,因此在结尾使用通配符*对未匹配内容进行匹配。
pattern中若有多个匹配规则,用|(或)连接,如1|2|3。可使用通配符、字符集([])。
循环结构
for
for variable in object ; do
command
done
-
传入列表:
for i in 1 2 3 4 5 ; do echo "$i" done -
传入范围序列
$(seq)(相当于Python的range(),注意Shell的seq的左闭右闭区间):for variable in $(seq start end [foot]) ; do command done -
传入花括号
{start..end}:等价于$(seq start end)$for variable in {start..end} ; do command done
while
while condition ; do
command
done
当condition为真时,循环执行循环体
until
until condition ; do
command
done
condition为假时,循环执行循环体,直到condition为真
跳转语句
continue:跳出循环的当前轮break:跳出整个循环
函数
- 函数定义
function_name() {
command
[return ...]
}
function function_name {
command
[return ...]
}
- 函数调用
function_name [argv,...]

浙公网安备 33010602011771号