连云港权威网站优化服务,网站代理 登陆,建设银行龙卡网站,股份有限公司概论
shell是我们通过命令行与操作系统沟通的语言
shell脚本可以直接在命令行中执行#xff0c;也可以将一套逻辑组织成一个文件#xff0c;方便复用。 DA Terminal中的命令行可以看成是一个“shell脚本在逐行执行”。
1.脚本示例
新建一个test.sh文件#xff0c;内容如…概论
shell是我们通过命令行与操作系统沟通的语言
shell脚本可以直接在命令行中执行也可以将一套逻辑组织成一个文件方便复用。 DA Terminal中的命令行可以看成是一个“shell脚本在逐行执行”。
1.脚本示例
新建一个test.sh文件内容如下
#! /bin/bash
echo Hello World!2.运行方式 作为可执行文件 acs9e0ebfcd82d7:~$ chmod x test.sh # 使脚本具有可执行权限
acs9e0ebfcd82d7:~$ ./test.sh # 当前路径下执行
Hello World! # 脚本输出
acs9e0ebfcd82d7:~$ /home/acs/test.sh # 绝对路径下执行
Hello World! # 脚本输出
acs9e0ebfcd82d7:~$ ~/test.sh # 家目录路径下执行
Hello World! # 脚本输出用解释器执行 acs9e0ebfcd82d7:~$ bash test.sh
Hello World! # 脚本输出注释
1.单行注释 每行中#之后的内容均是注释。 # 这是一行注释
echo Hello World # 这也是注释2.多行注释 格式 :EOF
第一行注释
第二行注释
第三行注释
EOF其中EOF可以换成其它任意字符串。例如 :abc
第一行注释
第二行注释
第三行注释
abc:!
第一行注释
第二行注释
第三行注释
!变量
1.定义变量 定义变量不需要加$符号例如 name1abc # 单引号定义字符串
name2abc # 双引号定义字符串
name3abc # 也可以不加引号同样表示字符串2.使用变量 使用变量需要加上 符号或者 符号或者 符号或者{}符号。 花括号是可选的主要为了帮助解释器识别变量边界。 namezhangsan
echo $name # 输出zhangsan
echo ${name} # 输出zhangsan
echo ${name}hello # 输出zhangsanhello3.只读变量 使用readonly或者declare可以将变量变为只读 nameabc
readonly name
declare -r name # 两种写法均可namedef # 会报错因为此时name只读4.删除变量 unset可以删除变量。 nameabc
unset name
echo $name # 输出空行5.变量类型 自定义变量局部变量子进程不能访问的变量 acs9e0ebfcd82d7:~$ nameabc # 定义变量
acs9e0ebfcd82d7:~$ export name # 第一种方法
acs9e0ebfcd82d7:~$ declare -x name # 第二种方法环境变量全局变量子进程可以访问的变量 acs9e0ebfcd82d7:~$ export nameabc # 定义环境变量
acs9e0ebfcd82d7:~$ declare x name # 改为自定义变量6.字符串 字符串可以用单引号也可以用双引号也可以不用引号 单引号与双引号的区别 单引号中的内容会原样输出不会执行、不会取变量双引号中的内容可以执行、可以取变量 nameabc # 不用引号
echo hello, $name \hh\ # 单引号字符串输出 hello, $name \hh\
echo hello, $name \hh\ # 双引号字符串输出 hello, abc hh获取长度与提取子串 nameabc
echo ${#name} # 输出3namehello, abc
echo ${name:0:5} # 提取从0开始的5个字符7.文件参数变量 在执行shell脚本时可以向脚本传递参数。 $1是第一个参数$2是第二个参数以此类推。特殊的$0是文件名包含路径。 #! /bin/bashecho 文件名$0
echo 第一个参数$1
echo 第二个参数$2
echo 第三个参数$3
echo 第四个参数$4acs9e0ebfcd82d7:~$ chmod x test.sh
acs9e0ebfcd82d7:~$ ./test.sh 1 2 3 4
文件名./test.sh
第一个参数1
第二个参数2
第三个参数3
第四个参数4其他参数相关变量 参数说明$#代表文件传入的参数个数如上例中值为4$*由所有参数构成的用空格隔开的字符串如上例中值为$1 $2 $3 $4$每个参数分别用双引号括起来的字符串如上例中值为$1 $2 $3 $4$$脚本当前运行的进程ID$?上一条命令的退出状态注意不是stdout而是exit code。0表示正常退出其他值表示错误$(command)返回command这条命令的stdout可嵌套command返回command这条命令的stdout 不可嵌套
8.数组
定义 数组用小括号表示元素之间用空格隔开 array(1 abc def hhh)也可以直接定义数组中某个元素的值 array[0]1
array[1]abc
array[2]def9.读取 读取数组中某个元素的值 ${array[index]}array(1 abc def hhh)
echo ${array[0]}
echo ${array[1]}
echo ${array[2]}读取整个数组 ${array[]} # 第一种写法
${array[*]} # 第二种写法array(1 abc def hhh)
echo ${array[]} # 第一种写法
echo ${array[*]} # 第二种写法10.数组长度 类似于字符串 ${#array[]} # 第一种写法
${#array[*]} # 第二种写法expr命令
shell中不可以直接通过表达式计算值这时候就要用到 expr 命令
1.使用 格式 expr 表达式表达式说明 用空格隔开每一项用反斜杠放在shell特定的字符前面发现表达式运行错误时可以试试转义对包含空格和其他特殊字符的字符串要用引号括起来expr会在stdout中输出结果。如果为逻辑关系表达式则结果为真stdout为1否则为0。
2.字符串表达式 length STRING返回字符串长度 index STRING CHARSET CHARSET中任意单个字符在STRING中最前面的字符位置下标从1开始依次寻找。找到则返回相应位置到最后也找不到则返回0 substr STRING POSITION LENGTH 返回STRING字符串中从POSITION开始长度最大为LENGTH的子串。如果POSITION或LENGTH为负数0或非数值则返回空字符串。 strHello World!echo expr length $str # 不是单引号表示执行该命令输出12
echo expr index $str aWd # 输出7下标从1开始
echo expr substr $str 2 3 # 输出 ell3.整数表达式
expr支持普通的算术操作算术表达式优先级低于字符串表达式高于逻辑关系表达式 -加减运算。两端参数会转换为整数如果转换失败则报错。 * / %乘除取模运算。两端参数会转换为整数如果转换失败则报错。 ()可以改变优先级但需要用反斜杠转移 a3
b4echo expr $a $b # 输出7
echo expr $a - $b # 输出-1
echo expr $a \* $b # 输出12*需要转义
echo expr $a / $b # 输出0整除
echo expr $a % $b # 输出3
echo expr \( $a 1 \) \* \( $b 1 \) # 输出20值为(a 1) * (b 1)4.逻辑关系表达式 | 如果第一个参数非空且非0则返回第一个参数的值否则返回第二个参数的值但要求第二个参数的值也是非空或非0否则返回0。如果第一个参数是非空或非0时不会计算第二个参数。 如果两个参数都非空且非0则返回第一个参数否则返回0。如果第一个参为0或为空则不会计算第二个参数。 ! 比较两端的参数如果为true则返回1否则返回0。””是””的同义词。”expr”首先尝试将两端参数转换为整数并做算术比较如果转换失败则按字符集排序规则做字符比较。 () 可以改变优先级但需要用反斜杠转义 a3
b4echo expr $a \ $b # 输出0需要转义
echo expr $a $b # 输出1也可以将特殊字符用引号引起来
echo expr $a $b # 输出0
echo expr $a \\ $b # 输出1c0
d5echo expr $c \ $d # 输出0
echo expr $a \ $b # 输出3
echo expr $c \| $d # 输出5
echo expr $a \| $b # 输出3read命令
read命令用于从标准输入中读取单行数据。当读到文件结束符时exit code为1否则为0
1.参数说明 -p: 后面可以接提示信息 -t后面跟秒数定义输入字符的等待时间超过等待时间后会自动忽略此命令 DAs9e0ebfcd82d7:~$ read name # 读入name的值
zhangsan # 标准输入
DAs9e0ebfcd82d7:~$ echo $name # 输出name的值
zhangsan #标准输出
DAs9e0ebfcd82d7:~$ read -p Please input your name: -t 30 name # 读入name的值等待时间30秒
Please input your name: zhangsan # 标准输入
DAs9e0ebfcd82d7:~$ echo $name # 输出name的值
zhangsan # 标准输出echo命令
此命令用于输出字符串
1.命令格式
echo STRING2.不同显示 显示普通字符 echo Hello
echo Hello # 引号可以省略显示转义字符 echo \Hello\ # 注意只能使用双引号如果使用单引号则不转义
echo \Hello\ # 也可以省略双引号显示变量 namezhangsan
echo My name is $name # 输出 My name is zhangsan显示换行 echo -e Hi\n # -e 开启转义
echo jony
Hi
jony显示不换行 echo -e Hi \c # -e 开启转义 \c 不换行
echo jonyHi jony显示结果定向至文件 echo Hello World output.txt # 将内容以覆盖的方式输出到output.txt中\\原样输出 nameDAwing
echo $name\显示命令执行结果 echo date
Wed Sep 1 11:45:33 CST 2021printf命令
printf命令用于格式化输出类似于C/C中的printf函数。默认不会在字符串末尾添加换行符。
printf %10d.\n 123 # 占10位右对齐
printf %-10.2f.\n 123.123321 # 占10位保留2位小数左对齐
printf My name is %s\n zhangsan # 格式化输出字符串
printf %d * %d %d\n 2 3 expr 2 \* 3 # 表达式的值作为参数123.
123.12 .
My name is zhangsan
2 * 3 6test命令与判断符号[]
1.逻辑运算符和|| 表示与|| 表示二者具有短路原则 expr1 expr2当expr1为假时直接忽略expr2expr1 || expr2当expr1为真时直接忽略expr2 表达式的exit code为0表示真为非零表示假。与C/C中的定义相反(可以理解为main函数正常运行时返回0)
2.test命令 在命令行中输入man test可以查看test命令的用法。 test命令用于判断文件类型以及对变量做比较。 test命令用exit code返回结果而不是使用stdout。0表示真非0表示假。 test 2 -lt 3 # 为真返回值为0
echo $? # 输出上个命令的返回值输出0DAs9e0ebfcd82d7:~$ ls # 列出当前目录下的所有文件
homework output.txt test.sh tmp
DAs9e0ebfcd82d7:~$ test -e test.sh echo exist || echo Not exist
exist # test.sh 文件存在
DAs9e0ebfcd82d7:~$ test -e test2.sh echo exist || echo Not exist
Not exist # testh2.sh 文件不存在3.关于文件 类型判断test -e filename # 判断文件是否存在 测试参数代表意义-e文件是否存在-f是否为文件-d是否为目录 权限判断test -r filename # 判断文件是否可读 测试参数代表意义-r文件是否可读-w文件是否可写-x文件是否执行-s是否为非空文件
4.比较与多重条件判定 整数间比较test $a -eq $b # a是否等于b 测试参数代表意义-eq判断两数是否相等-ne判断两数是否不等-gt是否大于关系-lt是否小于关系-ge是否大于等于关系-le是否小于等于关系 字符串比较 测试参数代表意义test -z STRING判断字符串是否为空test -n STRING判断字符串是否非空test str1 str2断字符串是否相等test str1 ! str2判断字符串是否不等 多重条件判定test -r filename -a -x filename 测试参数代表意义-a两条件是否同时成立-o两条件是否至少成立一个!取反当文件不可执行时返回true
5.判断符号[]
**[]与test用法几乎一模一样更常用于if语句中。另外[[]]是[]的加强版支持的特性更多。 ** 前半括号后必须用空格隔开
[ 2 -lt 3 ] # 为真返回值为0
echo $? # 输出上个命令的返回值输出0
DAs9e0ebfcd82d7:~$ ls # 列出当前目录下的所有文件
homework output.txt test.sh tmp
DAs9e0ebfcd82d7:~$ [ -e test.sh ] echo exist || echo Not exist
exist # test.sh 文件存在
DAs9e0ebfcd82d7:~$ [ -e test2.sh ] echo exist || echo Not exist
Not exist # testh2.sh 文件不存在注意 []内的每一项都要用空格隔开中括号内的变量最好用双引号括起来中括号内的常数最好用单或双引号括起来 namezhang san
[ $name zhang san ] # 错误等价于 [ zhang san zhang san ]参数太多
[ $name zhang san ] # 正确判断语句
if…then形式类似于C/C中的if-else语句 单层if if condition
then语句1语句2...
fia3
b4if [ $a -lt $b ] [ $a -gt 2 ]
thenecho ${a}在范围内
fi单层if-else if condition
then语句1语句2...
else语句1语句2...
fi多层if-elif-elif-else if condition
then语句1语句2...
elif condition
then语句1语句2
else语句1语句2...
ficase...esDA形式 case $变量名称 in值1)语句1语句2...;; # 类似于C/C中的break值2)语句1语句2...;;*) # 类似于C/C中的default语句1语句2...;;
esDA循环语句 for…in…do…done命令格式 for var in val1 val2 val3
do语句1语句2...
done#输出1-10
for i in $(seq 1 10)#第一个数为1最后一个数为10
doecho $i
done#输出a-z
for i in {a..z}
doecho $i
donefor ((…;…;…)) do…done命令格式 for ((expression; condition; expression))
do语句1语句2
done#类似于c语言的循环
for ((i1; i10; i))
doecho $i
donewhile…do…done循环命令格式 while condition
do语句1语句2...
done#示例文件结束符为Ctrld输入文件结束符后read指令返回false
while read name
doecho $name
doneuntil…do…done循环当条件为真时结束 until condition
do语句1语句2...
done#示例当用户输入yes或者YES时结束否则一直等待读入。
until [ ${word} yes ] || [ ${word} YES ]
doread -p Please input yes/YES to stop this program: word
donebreak命令与continue命令 break跳出当前一层循环注意与C/C不同的是break不能跳出case语句continue跳出当前循环
死循环的处理方式
如果DA Terminal可以打开该程序则输入Ctrlc即可否则可以直接关闭进程 使用top命令找到进程的PID输入kill -9 PID即可关掉此进程
函数
1.概要 return的返回值返回的是exit code取值为0-2550表示正常结束。 如果想获取函数的输出结果可以通过echo输出到stdout中然后通过$(function_name)来获取stdout中的结果 函数的return值可以通过$?来获取。 [function] func_name() { # function关键字可以省略语句1语句2...
}2.不获取return值和stdout值
func() {namezhangsanecho Hello $name
}func#Hello zhangsan3.获取return值和stdout值
不写return时默认return 0。
func() {nameabcecho Hello $namereturn 123
}output$(func)
ret$?echo output $output
echo return $ret#output Hello abc
#return 1234.函数的输入参数
在函数内$1表示第一个输入参数$2表示第二个输入参数依此类推。注意函数内的$0仍然是文件名而不是函数名。
func() { # 递归计算 $1 ($1 - 1) ($1 - 2) ... 0wordwhile [ ${word} ! y ] [ ${word} ! n ]doread -p 要进入func($1)函数吗请输入y/n worddoneif [ $word n ]thenecho 0return 0fi if [ $1 -le 0 ] thenecho 0return 0fi sum$(func $(expr $1 - 1))echo $(expr $sum $1)
}echo $(func 10)5.函数内的局部变量
可以在函数内定义局部变量作用范围仅在当前函数内。可以在递归函数中定义局部变量。命令格式local 变量名变量值
#! /bin/bashfunc() {local nameabcecho $name
}
funcecho $nameexit命令 exit命令用来退出当前shell进程并返回一个退出状态使用$?可以接收这个退出状态。 exit命令可以接受一个整数值作为参数代表退出状态。如果不指定默认状态值是 0。 exit退出状态只能是一个介于 0~255 之间的整数其中只有 0 表示成功其它值都表示失败。 #! /bin/bashif [ $# -ne 1 ] # 如果传入参数个数等于1则正常退出否则非正常退出。
thenecho arguments not validexit 1
elseecho arguments validexit 0
fiacs9e0ebfcd82d7:~$ chmod x test.sh
acs9e0ebfcd82d7:~$ ./test.sh abc
arguments valid
acs9e0ebfcd82d7:~$ echo $? # 传入一个参数则正常退出exit code为0
0
acs9e0ebfcd82d7:~$ ./test.sh
arguments not valid
acs9e0ebfcd82d7:~$ echo $? # 传入参数个数不是1则非正常退出exit code为1
1文件重定向
1.概述
stdin标准输入从命令行读取数据文件描述符为0stdout标准输出向命令行输出数据文件描述符为1stderr标准错误输出向命令行输出数据文件描述符为2
2.重定向命令列表
命令说明command file将stdout重定向到file中command file将stdin重定向到file中从文件中写入command file将stdout以追加的方式重定向到file中command n file将文件描述符n重定向到file中command n file将文件描述符n以追加方式重定向到file中
3.输入和输出重定向
echo -e Hello \c output.txt # 将stdout重定向到output.txt中
echo World output.txt # 将字符串追加到output.txt中read str output.txt # 从output.txt中读取字符串echo $str # 输出结果Hello World4.同时重定io
acs9e0ebfcd82d7:~$ chmod x test.sh # 添加可执行权限
acs9e0ebfcd82d7:~$ ./test.sh input.txt output.txt # 从input.txt中读取内容将输出写入output.txt中
DAs9e0ebfcd82d7:~$ cat output.txt # 查看output.txt中的内容
7引入外部脚本 语法格式 . filename # 注意点和文件名之间有一个空格
#或
source filename示例 #创建test1.sh
#! /bin/bashnameabc # 定义变量name#创建test2.sh
#! /bin/bashsource test1.sh # 或 . test1.shecho My name is: $name # 可以使用test1.sh中的变量