linux常用命令总结(四、编写Shell脚本)

一、运行Shell脚本

shell基础

#! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell。

执行脚本

执行脚本的两种方法:

1.
chmod 755 file.sh    先修改可执行权限
cd到当前目录下 
使用 ./file.sh   file.sh为执行的脚本名称

2.通过bash调用
bash file.sh

如果是html文本
使用firefox浏览器执行: firefox file

使用echo命令进行文本时,使用的引号可以包含换行符,因此可以包含多个文本行。

使用echo -e选项可以支持\控制的字符转换

变量和常量

创建变量和常量

创建变量直接创建 例如: foo="hello"

运用时 需使用 $+变量名

强制常量不发生变化 使用declare命令的-r选项

declare -r foo="hello"   foo后面将不会再被改变 相当于c++z中的const

为变量和常量赋值

shell并不关心赋给变量的值的数值类型,可以通过declare命令的-i选项,强制shell将变量限制为整数类型。

在赋值时,变量名、等号和值之间不能含有空格。

a=z                  将字符串z赋值给a
b="a string"         嵌入的空格必须用引号引起来
c="a string and $b"  可以被扩展到赋值语句中的其他扩展、比如变量
d=$((5*7))           算术扩展
e=$(ls -l foo.txt)   命令的结果
f="\t\ta string\n"   转义序列 比如制表符和换行符

可以在一行中对多个变量赋值。

当字符变量因为上下文变得并不明确时 可以使用{}

here文档

除了使用echo命令进行文本输出,here文档是I/O重定向的另一种形式。

工作形式如下:

command << token
text
token

其中command是接收标准输入的文件名,token是用来指示嵌入文本结尾的字符串。

cat << _EOF_
...
_EOF_

_EOF_被选作token,表示文本的结尾 token必须单独一行出现,并且文本行的末尾没有空格

二、自顶向下设计

shell函数

shell函数有两种语法形式:

function name{
	commands
	return
}
其中name是指这个函数的名称,commands是这个函数的一系列指令

name(){
	commands
	return
}

局部变量

局部变量是通过在变量名前添加单词local来定义。

三、if分支语句

使用if

if语句的语法格式:

if commands; then
	commands
[elif commands; then
	commands...]
[else
	commands]
fi
commands可以是一组命令 可使用;隔开
会以最后一个命令的执行结果作为评判标准

退出状态

命令在执行完毕后,会向操作系统发送一个0~255的值,用来指示命令执行成功还是失败。其中,数值0表示成功,其他的值表示执行失败。

对于每个命令可以检测退出状态:

echo $?   输出0表示成功退出

使用test命令

test命令经常与if一起使用,会执行各种检查和比较。

有两种等价的形式:

test expression  或者   [ expression ] 
其中expression是一个表达式,其结果是true或false
[]间必须有空格

下面介绍一些表达式expression

文件表达式

测试文件的表达式用来评估文件的状态:

表达式                          成为true的条件
file1 -ef file2                file1与file2拥有相同的信息节点编号
file1 -nt file2                file1比file2新
file1 -ot file2                file1比file2旧
-b file                        file存在并且是一个块文件
-c file                        file存在并且是一个字符文件
-d file                        file存在并且是一个目录
-e file                        file存在
-f file                        file存在并且是普通文件
省略其余部分 参考p332

字符串表达式

测试字符串的表达式用来测试字符串的操作:

表达式                          成为true的条件
string                         string不为空
-n string                      string的长度大于0
-z string                      string的长度等于0
string1=string2				   string1和string2相等,双引号使用更多
string1==string2
string1!=string2               string1不等于string2
string1>string2				   在排序时,string1在string2后
string1<string2				   在排序时,string1在string2前

在使用’<’ '>'时,必须用引号括起来,或者使用反斜杠进行转义,不然会被解释为重定向符号。

整数表达式

整数判断操作:

表达式                          成为true的条件
a -eq b                        a与b相等
a -ne b                        a与b不相等
a -le b                        a小于等于b
a -lt b                        a小于b
a -ge b                        a大于等于b
a -gt b                        a大于b

e equal n not l less g greater 

更现代的test命令版本

语法: [[ expression ]] expression是一个表达式 结果为true或false

增加了很重要的新字符串表达式:string1=~regex

x=-5
if [["$x"=~ ^-?[0-9]+$ ]] then...

如果string1与扩展的正则表达式regex匹配,则返回true

[[]] 另一个特性是==操作符支持模式匹配:

file=foo.bar
if [[ $file==foo.* ]];then...

[[ 和 ]]之间不能有空格

组合表达式

与test和[[]]命令配套的逻辑运算有三个,分别是AND,OR,NOT

逻辑操作符:

operation       test                [[]]或(())
AND             -a                  &&
OR              -o                  ||
NOT             !                   !

由于test命令使用的所有表达式和操作符都被shell看作命令参数,不像[[]]或(())一样,因此在bash中含有特殊含义的字符如’<’,’>’,’(’,’)'必须使用引号括起来或者进行转义。

四、读取键盘输入

read命令 从标准输入读取输入值

内嵌命令read的作用是读取一行标准输入。
可用于读取键盘输入值或应用重定向文件读取文件的一行。

read命令的语法结构为:

read [-options] [variable...]
options为参数选项, variable是一到多个用于存放输入值的变量

read常用的参数选项

-a array             将输入值从索引为0的位置开始赋给array
-d delimiter         用字符串delimiter的第一个字符标志输入的结束,而不是新的一行的开始
-n num               从输入中读取num个字符,而不是一整行
-p prompt			 使用prompt字符串提示用户进行输入
-r                   原始模式 不能将后斜线字符翻译为转义码
-s					 保密模式  不在屏幕显示
-t seconds           超时,在seconds秒后结束输入
-u fd                从文件说明符fd读取输入,而不是从标准输入中读取

如果read命令读取的值少于预期的数目,则多余的变量值为空,而输入的值数目超过预期的数量时,最后的一个变量包含了所有的多余值。

如果read命令后无变量,则会为所有输入分配一个shell变量:REPLY

使用IFS间隔输入字段

通常shell会间隔提供给read的内容,此行为有shell变量IFS设定,IFS设定值包含空格、制表符、换行符。

如果已知数据,不需要从键盘读取,可以使用’<<<'操作符,象征一条嵌入字符串。

read不可重定向!

五、WHILE和UNTIL循环

while

while循环的语法结构:

while [ 条件判断语句 ]
	do
		程序
	done
或者
while commands; do commands; done

如需跳出循环,可使用continue和break语句 ,同c语言用法

until

while命令退出状态不为0时终止逊环,而until命令则刚好相反。

如果添加判断式不成立,则循环,成立则退出循环。

语法结构同while循环

使用循环读取文件

while与nutil可处理标准输入。

为了将一份文件重定向到循环中,可以在done后添加重定向符号,实例:

while read a b c; do
	...
done < foo.txt
从foo.txt文件中读取a b c 参数

还可以使用管道进行读取:

sort -k 1,1, -k 2n foo.txt | while read a b c; do
	...
done
此脚本或取sort命令的输出,但是,管道是在子shell中进行循环,所以循环终止时,
循环内部新建的变量或对变量的赋值效果都会丢失。

六、case分支

bash的多项选择符合命令被称为case。case只能判断一种条件关系

其语法形式为:

case word in
		[pattern [| pattern]...) commands ;;]...
esac

简化
case $变量名 in
	1)
		commands
		;;
	2)
		commands
		;;
esac

模式

case使用’)'字符结尾的模式。

case模式范例:

a)               若关键字为a则吻合
[[:alpha:]]      若关键字为单个字母则吻合
???)             若关键字为三个字符则吻合
*.txt)           若关键字以.txt结尾则吻合
*)               任何关键字都吻合

多个模式的组合

使用竖线作为分隔符来组合多个模式,满足其一即可。

七、位置参数

位置参数变量有

$n            n为数字,$0代表命令本身,$1-$9代表第一到第九个参数,十以上的参数需要用大括号例如 {$10}
$*            这个变量代表命令行中所有的参数,把所有的参数看成一个整体
$@            这个变量也代表命令中所有的参数,不过$@把每个参数区分对待
$#            这个参数代表命令行中参数个数

八、For循环

原始的for命令语法如下:

for variable [in words]; do
	commands
done

其中,variable是一个在循环执行时会增加的变量名,words是一列将按顺序付给变量variable的可选项,commands部分是每次循环需要执行的命令。

for i in A B C D;do
	echo "$i"
done

c语言形式:

for (( expression1;expression2;expression ));do
	commands
done

其中expression1,expression2,expression3为算术表达式,commands是每次循环都要执行的命令。

for (( i=0;i<5;i++ ));do
	echo $i
done

九、字符串和数组

参数扩展

基本参数

普通变量用{}括起来防止shell将其与邻近文本混淆。

空变量扩展的管理

有的参数扩展用于处理不存在的变量和空变量。在解决缺失的位置参数和给参数赋默认值时很有用。

形式为:

${parameter:-word}
如果参数parameter未被设定或是空参数,则其扩展为word的值,如果非空,则为parameter的值

${parameter:=word}
如果参数parameter未被设定或是空参数,则其扩展为word的值,如果非空,则为parameter的值

${parameter:?word}
如果参数parameter未被设定或是空参数,则会导致脚本错误并退出,并且word内容输出到标准错误,如果非空,则为parameter的值

${parameter:+word}
如果参数parameter未被设定或是空参数,则不产生任何扩展,如果非空,则为word的值

返回变量名的扩展

${!prefix*}
${!prefix@}

该扩展返回当前以prefix开头的变量名

字符串操作

${#parameter}
扩展为parameter内包含的字符串长度,一般来说参数parameter是个字符串,
如果参数parameter是"@"或"#",扩展结果就是位置参数的个数。

${parameter:offset}
${parameter:offset:length}
这个扩展用于提取一部分包含在参数parameter中的字符串,扩展以offset开始,直到字符串结尾,除非length指定。
如果offset的值为负,默认从字符串尾部开始,注意,负值前面必须要有空格,防止与${parameter:-word}混淆。

${parameter#pattern}
${parameter##pattern}
根据pattern定义,去除包含在parameter中的字符串的主要部分。
pattern是一个通配符模式,类似路径名的扩展。
两种形式区别在于 #形式去除最短匹配,##形式去除最长匹配。

${parameter%pattern}
${parameter%%pattern}
同上述扩展相同,只是此扩展从参数包含的字符串末尾去除文本。

${parameter/pattern/string}
${parameter//pattern/string}
${parameter/#pattern/string}
${parameter/%pattern/string}
此扩展在parameter的内容上可执行搜索和替换,如果文本和pattern一致,则被替换为string的内容。
通常形式下,只有第一个pattern被替换,在"//"形式下,所有的被替换,在"/#"形式下,要求匹配出现在字符串开头,在"/%"形式下,要求匹配出现在字符串末尾。
/string可省略,不过匹配的内容将会被删除。

十、数组

创建一个数组

命名数组变量同其他bash变量一样,访问时可以自动创建

a[1]=foo

使用declare命令也可以创建数组:

declare -a a   使用declare的-a    选项创建数组名为a 

数组赋值

name[subscript]=value   	name是数组名,subscript是>=0的整数
name=(value1,value2...)     为数组多个位置赋值  从下标0开始
name=([0]=1 [2]=3 [5]=6)    为特定位置赋值

数组操作

输出数组的所有内容

使用下标"@“和”*“访问数组的每个元素,注意使用”“与不使用”"遍历时不同。

确定数组元素的数目

使用#符号

查找数组中使用的下标

${!array[*]}
${!array[@]}
array是数组变量名,遍历时输出数组中赋有值的位置

在数组的结尾增加变量

使用+=符号

foo=(a b c)
foo+=(e d f)   

数组排序操作

a=(a b c d e)
a_sorted=($(for i in "${a[@]}";do echo $i;done | sort))
使用复制数组,遍历a数组 然后调用sort命令进行输出

数组的删除

使用unset命令进行删除整个数组。 直接 unset 数组名

删除单个数组元素 unset ‘数组名[位置]’

对数组赋空值,只会删除数组的第一个位置,即0位置

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值