学一下shell编程

Shell变量

(1)定义变量的时候,赋值号=周围不能有空格

(2)定义变量时不需要$符号,而使用变量时可以用$var或这${var},推荐使用${}的方式,便于解释器识别变量边界。

name="Lethe"
echo ${name}

(3)单引号与双引号的区别

  • 单引号''包围变量的值时,单引号里面是什么就输出什么,即使内容中有变量和命令(命令需要反引起来)也会把它们原样输出。
  • 双引号""包围变量的值时,输出时会先解析里面的变量和命令。

(4)将命令的执行结果赋给一个变量有下面两种方式:

  • 反引号
    在这里插入图片描述
  • $() (推荐使用)
    在这里插入图片描述
    (5)计算表达式:$(())
    在这里插入图片描述
    (6)通过readonly可以将变量声明为只读变量,只读变量不能被改变,也不能被unset命令删除。
    在这里插入图片描述

Shell特殊变量

(1)特殊变量列表

变量含义
$0当前脚本的文件名
$n传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。
$#传递给脚本或函数的参数个数。
$*传递给脚本或函数的所有参数。
$@传递给脚本或函数的所有参数。被双引号(" ")包含时,与 $* 稍有不同。
$?上个命令的退出状态,或函数的返回值。
$$当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。
#!/bin/bash
echo "File Name: $0"
echo "First Parameter : $1"
echo "First Parameter : $2"
echo "Quoted Values: $@"
echo "Quoted Values: $*"
echo "Total Number of Parameters : $#"

在这里插入图片描述

(2)$*$@的区别
$*$@ 都表示传递给函数或脚本的所有参数,不被双引号(" ")包含时,都以"$1" "$2" … "$n" 的形式输出所有参数。

但是当它们被双引号(" ")包含时:

  • "$*" 会将所有的参数作为一个整体,以"$1 $2 … $n"的形式输出所有参数;
  • "$@" 会将各个参数分开,以"$1" "$2" … "$n"的形式输出所有参数。

Shell替换

(1)如果表达式中包含特殊字符,Shell 将会进行替换。例如,在双引号中使用变量就是一种替换,转义字符也是一种替换。
在这里插入图片描述
这里 -e 表示对转义字符进行替换。如果不使用 -e 选项,将会原样输出。

下面的转义字符都可以用在 echo 中:

转义字符含义
\\反斜杠
\a警报,响铃
\b退格(删除键)
\f换页(FF),将当前位置移到下页开头
\n换行
\r回车
\t水平制表符(tab键)
\v垂直制表符

也可以使用 echo 命令的 -E 选项禁止转义,默认也是不转义的;使用 -n 选项可以禁止插入换行符。

(2)命令替换

命令替换是指Shell可以先执行命令,将输出结果暂时保存,在适当的地方输出。
在这里插入图片描述

(3)变量替换

变量替换可以根据变量的状态(是否为空、是否定义等)来改变它的值。

可以使用的变量替换形式:

形式说明
${var}变量本来的值
${var:-word}如果变量 var 为空或已被删除(unset),那么返回 word,但不改变 var 的值。
${var:=word}如果变量 var 为空或已被删除(unset),那么返回 word,并将 var 的值设置为 word。
${var:?message}如果变量 var 为空或已被删除(unset),那么将消息 message 送到标准错误输出,可以用来检测量 var 是否可以被正常赋值。若此替换出现在Shell脚本中,那么脚本将停止运行。
${var:+word}如果变量 var 被定义,那么返回 word,但不改变 var 的值。
#!/bin/bash

echo ${var:-"Variable is not set"}
echo "1 - Value of var is ${var}"

echo ${var:="Variable is not set"}
echo "2 - Value of var is ${var}"

unset var
echo ${var:+"This is default value"}
echo "3 - Value of var is $var"

var="Prefix"
echo ${var:+"This is default value"}
echo "4 - Value of var is $var"

echo ${var:?"Print this message"}
echo "5 - Value of var is ${var}"

在这里插入图片描述


Shell运算符

(1)原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。
在这里插入图片描述

  • 表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2
  • 完整的表达式要被反引号包含

(2)算数运算符

运算符说明举例
+加法`expr $a + $b` 结果为 30。
-减法`expr $a - $b` 结果为 10。
*乘法`expr $a * $b` 结果为 200。
/除法`expr $b / $a` 结果为 2。
%取余`expr $b % $a` 结果为 0。
=赋值a=$b 将把变量 b 的值赋给 a。
==相等。用于比较两个数字,相同则返回 true。[ $a == $b ] 返回 false。
!=不相等。用于比较两个数字,不相同则返回 true。[ $a != $b ] 返回 true。
  • 乘号(*)前边必须加反斜杠()才能实现乘法运算;
  • 条件表达式要放在方括号之间,并且要有空格,例如 [$a==$b] 是错误的,必须写成 [ $a == $b ]

(3)关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。

运算符说明举例
-eq检测两个数是否相等,相等返回 true,相当于==[ $a -eq $b ] 返回 true。
-ne检测两个数是否相等,不相等返回 true,相当于!=[ $a -ne $b ] 返回 true。
-gt检测左边的数是否大于右边的,如果是,则返回 true,相当于>[ $a -gt $b ] 返回 false。
-lt检测左边的数是否小于右边的,如果是,则返回 true,相当于<[ $a -lt $b ] 返回 true。
-ge检测左边的数是否大等于右边的,如果是,则返回 true,相当于>=[ $a -ge $b ] 返回 false。
-le检测左边的数是否小于等于右边的,如果是,则返回 true,相当于<=[ $a -le $b ] 返回 true。

(4)布尔运算符

运算符说明举例
!非运算,表达式为 true 则返回 false,否则返回 true。[ ! false ] 返回 true。
-o或运算,有一个表达式为 true 则返回 true。[ $a -lt 20 -o $b -gt 100 ] 返回 true。
-a与运算,两个表达式都为 true 才返回 true。[ $a -lt 20 -a $b -gt 100 ] 返回 false。

(5)字符串运算符

运算符说明举例
=检测两个字符串是否相等,相等返回 true。[ $a = $b ] 返回 false。
!=检测两个字符串是否相等,不相等返回 true。[ $a != $b ] 返回 true。
-z检测字符串长度是否为0,为0返回 true。[ -z $a ] 返回 false。
-n检测字符串长度是否为0,不为0返回 true。[ -z $a ] 返回 true。
str检测字符串是否为空,不为空返回 true。[ $a ] 返回 true。

Shell注释

  • 以“#”开头的行就是注释,会被解释器忽略。

  • sh里没有多行注释,只能每一行加一个#号

Shell字符串

(1)拼接字符串

string1="Hello"
string2="World"
echo $string1 $string2 # 输出Hello World

(2)获取字符串长度

string="abcd"
echo ${#string} #输出 4

(3)提取子字符串

string="Hello Word"
echo ${string:1:4} #输出ello

(4)查找子字符串

string="Hello World"
echo `expr index "$string" lo` # 输出3

Shell数组

(1)定义数组
在Shell中,用括号来表示数组,数组元素用“空格”符号分割开

array_name=(value0 value1 value2 value3)

或单独定义数组的各个分量:

array_name[0]=value0
array_name[1]=value1
array_name[2]=value2

可以不使用连续的下标,而且下标的范围没有限制。

(2)读取数组

读取数组格式:${array_name[index]}

valuen=${array_name[2]}
  • 使用@*可以获取数组中的所有元素。
${array_name[*]}
${array_name[@]}
  • 获取数组长度的方法与获取字符串长度的方法相同
# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
lengthn=${#array_name[n]}

if else语句

(1)if … else 语句

if [ expression ]
then
   Statement(s) to be executed if expression is true
fi
  • 如果 expression 返回 true,then 后边的语句将会被执行;如果返回 false,不会执行任何语句。
  • 最后必须以 fi 来结尾闭合 if。
  • expression 和方括号([ ])之间必须有空格,否则会有语法错误。

(2)if … else … fi 语句

if [ expression ]
then
   Statement(s) to be executed if expression is true
else
   Statement(s) to be executed if expression is not true
fi

如果 expression 返回 true,那么 then 后边的语句将会被执行;否则,执行 else 后边的语句。

(3)if … elif … fi 语句

if [ expression 1 ]
then
   Statement(s) to be executed if expression 1 is true
elif [ expression 2 ]
then
   Statement(s) to be executed if expression 2 is true
elif [ expression 3 ]
then
   Statement(s) to be executed if expression 3 is true
else
   Statement(s) to be executed if no expression is true
fi

哪一个 expression 的值为 true,就执行哪个 expression 后面的语句;如果都为 false,那么不执行任何语句。

(4)if … else 语句也可以写成一行,以命令的方式来运行,像这样:

if test $[2*3] -eq $[1+5]; then echo 'The two numbers are equal!'; fi;

test 命令用于检查某个条件是否成立,与方括号([ ])类似。


case esac语句

case 语句匹配一个值或一个模式,如果匹配成功,执行相匹配的命令,与其他语言的switch … case类似。

case语句格式如下:

casein
模式1)
    command1
    command2
    command3
    ;;
模式2)
    command1
    command2
    command3
    ;;
*)
    command1
    command2
    command3
    ;;
esac

例子:

#!/bin/bash
option="${1}"
case ${option} in
   -f) FILE="${2}"
      echo "File name is $FILE"
      ;;
   -d) DIR="${2}"
      echo "Dir name is $DIR"
      ;;
   *) 
      echo "`basename ${0}`:usage: [-f file] | [-d directory]"
      exit 1 # Command to come out of the program with status 1
      ;;
esac

运行结果:

$./test.sh
test.sh: usage: [ -f filename ] | [ -d directory ]
$ ./test.sh -f index.htm
$ vi test.sh
$ ./test.sh -f index.htm
File name is index.htm
$ ./test.sh -d unix
Dir name is unix
$

for循环

格式如下:

for 变量 in 列表
do
    command1
    command2
    ...
    commandN
done
  • 列表是一组值(数字、字符串等)组成的序列,每个值通过空格分隔。每循环一次,就将列表中的下一个值赋给变量。

  • in 列表是可选的,如果不用它,for 循环使用命令行的位置参数。

#!/bin/bash
for loop in 1 2 3 4 5
do
	echo "The value is: $loop"
done

在这里插入图片描述


while循环

while循环用于不断执行一系列命令,也用于从输入文件中读取数据;命令通常为测试条件。其格式为:

while command
do
   Statement(s) to be executed if command is true
done

例子:

#!/bin/bash
count=0
while [ $count -lt 5]
do
	count=`expr $count + 1`
	echo $count
done

在这里插入图片描述


until循环

until 循环执行一系列命令直至条件为 true 时停止。until 循环与 while 循环在处理方式上刚好相反。

until command
do
   Statement(s) to be executed until command is true
done

break和continue命令

(1)break

  • break命令允许跳出所有循环(终止执行后面的所有循环)。
  • 在嵌套循环中,break 命令后面还可以跟一个整数,表示跳出第几层循环。例如:
break n

表示跳出第 n 层循环。

(2)continue

  • continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。
  • continue 后面也可以跟一个数字,表示跳出第几层循环。

Shell函数

Shell函数的定义格式如下:

function_name() {
	list of commands
	[ return value ]
}

Shell 函数返回值只能是整数,一般用来表示函数执行成功与否,0表示成功,其他值表示失败。

如果 return 其他数据,比如一个字符串,往往会得到错误提示:“numeric argument required”。

如果一定要让函数返回字符串,那么可以先定义一个变量,用来接收函数的计算结果,脚本在需要的时候访问这个变量来获得函数返回值。

例子:

#!/bin/bash
funWithReturn(){
    echo "The function is to get the sum of two numbers..."
    echo -n "Input first number: "
    read aNum
    echo -n "Input another number: "
    read anotherNum
    echo "The two numbers are $aNum and $anotherNum !"
    return $(($aNum+$anotherNum))
}
funWithReturn
# Capture value returnd by last command
ret=$?
echo "The sum of two numbers is $ret !"

在这里插入图片描述

在函数内部可以用 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数…

特殊变量说明
$#传递给函数的参数个数。
$*显示所有传递给函数的参数。
$@与$*相同,但是略有区别,请查看Shell特殊变量。
$?函数的返回值。

输入输出重定向

一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:

  • 标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
  • 标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
  • 标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息
命令说明
command > file将输出重定向到 file。
command < file将输入重定向到 file。
command >> file将输出以追加的方式重定向到 file。
n > file将文件描述符为 n 的文件重定向到 file。
n >> file将文件描述符为 n 的文件以追加的方式重定向到 file。
n >& m将输出文件 m 和 n 合并。
n <& m将输入文件 m 和 n 合并。
<< tag将开始标记 tag 和结束标记 tag 之间的内容作为输入。

Shell文件包含

Shell 中包含脚本可以使用:

. filename

source filename

通常使用点号.,注意点号.和文件名中间有一空格。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值