Shell基础学习笔记

291 阅读4分钟

一、变量

shell变量的定义与其他语言并没有什么区别。主要注意一下几点

  1. shell变量没有赋值的时候。会被当做命令执行
  2. shell变量。可以是值。也可以是命令。可以是命令返回值,函数返回值。反正挺广泛的(泛型)。

1.1 变量类型

  1. 局部变量 当前脚本内部定义的变量。其他脚本不能访问
  2. 环境变量 所有程序都能方位的变量。比如PATH
  3. shell变量 由shell程序设置的特殊变量,可能是局部,也可能是环境(不是很懂。。)
  • shell脚本继承。貌似是不能继承局部变量。

1.2 变量使用

变量使用 一般使用变量:${变量名} 或者 $变量名 。推荐第一种。

当命令作为变量的时候 可以使用“``” 反引号内部添加变量名的方式。另外 $() 也可以。通常后一种适用于内部命令有操作的情况。例如

workspacePostFix=".xcworkspace"
file_a="/demo/demo.xcworkspace"
# grep 正则的用法。下面的这个命令。意思是打印出file_a 变量名.进行匹配,如果包含。则赋值给result 。如果不包含则赋值为空
result=$(echo $file_a | grep "${workspacePostFix}") 
  • shell变量赋值。=赋值符号两边不能有空格。

1.3 变量相关命令

  1. readonly 只读
#!/bin/bash
myUrl="http://www.w3cschool.cc"
readonly myUrl
myUrl="http://www.runoob.com"
  1. unset 删除变量
#!/bin/sh
myUrl="http://www.runoob.com"
unset myUrl
echo $myUrl

二、字符串

2.1 字符串定义

shell 中字符串定义可以是单引号,也可以用双引号

'字符串'
"字符串"

区别在于

  1. 单引号字符串,就是字符串,不可更改
str='字符串'
  1. 双引号字符串,可以赋值
str='字符串1'
str2="我是:${str}"

2.2字符串截取

#1. # 号截取,删除左边字符,保留右边字符。
var=http://www.aaa.com/123.htm
echo ${var#*/}(其中 *为通配符,代表所有字符串,截取从“/”开始)
#2. ## 号截取,删除左边字符,保留右边字符。
echo ${var##*/}
#3. %号截取,删除右边字符,保留左边字符
echo ${var%/*}
#4. %% 号截取,删除右边字符,保留左边字符
echo ${var%%/*}
#5. 从左边第几个字符开始,及字符的个数
echo ${var:0:5}
#6. 从左边第几个字符开始,一直到结束。
echo ${var:7}
#7. 从右边第几个字符开始,及字符的个数
echo ${var:0-7:3}
#其中的 0-7 表示右边算起第七个字符开始,3 表示字符的个数。
#8. 从右边第几个字符开始,一直到结束。
echo ${var:0-7}
#表示从右边第七个字符开始,一直到结束。

三、数组

shell中没有 key-value 类型的键值映射存储结构。一般存储都使用数组来完成

3.1 定义

用括号表示数组,用空格隔开。shell中只支持一维数组。不支持多维数组

array_name=(value1 valu2 valu3)

3.2 数组赋值和读取

3.2.1 数组赋值

array_name=(value1 valu2 valu3)
array_name[0]=value4

3.2.2 读取数组

valuen=${array_name[2]}

3.2.3 获取数组长度

length=${array_name[@]}
length=${array_name[*]}

3.2.4 获取数组单个元素长度

lengthn=${array_name[n]}

3.2.5 获取数组总所有元素

${array_name[@]}
${array_name[*]}

四、运算符

4.1常规运算

4.1.1 算数运算

与其他语言运算一致,唯一区别即,原生bash不支持算数运算,需要借助 awk 和expr两个命令完成。其中以expr最常用

va =`expr 2 + 2` 

注意,必须使用反引号` 而不是单引号;还有就是2 + 2 中间必须有空格 反引号 内部括起来的,是当做命令执行的,而且执行结果作为变量,比如

`pwd`

4.1.2 关系运算符

a=10 b=20

  • -eq 检测两个数是否相等 例: [$a -eq $b] false
  • -ne 检测两个数是否不相等 例 : [$a -ne $b] true
  • -gt 检测左边的数是否大于右边的数 例: [$a -gt $b] false
  • -lt 检测左边的数是否小于右边的数 例: [$a -lt $b] true
  • -ge 检测左边的数是否大于等于右边的数 例 : [$a -ge $b] false
  • -le 检测左边的数是否小于等于右边的数 例: [$a -le $b] true

4.1.3布尔运算符

  • ! 非
  • -o 或 [$a -lt 20 -o $b -gt 100]
  • -a 与 [$a -lt 20 -a $b -gt 100]

4.1.4 逻辑运算符

  • && 逻辑的 AND

[[ $a -lt 100 && $b -gt 100 ]] 返回 false

  • || 逻辑的 OR

[[ $a -lt 100 || $b -gt 100 ]] 返回 true

4.1.5字符串运算符

下表列出了常用的字符串运算符,假定变量

a="abc"

b="efg"

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

运算符详解见运算符详解

五、流程控制

流程控制,一般就包括 if 条件判断 for循环 while循环 case几种

5.1 if 条件判断

if 语法格式如下

if [条件代码]
then
    执行代码
fi

举例说明

a=10
b=20
if [ $a == $b ]
then
   echo "a 等于 b"
elif [ $a -gt $b ]
then
   echo "a 大于 b"
elif [ $a -lt $b ]
then
   echo "a 小于 b"
else
   echo "没有符合的条件"
fi
  • 另外 if条件判断中可能会涉及一个特殊命令 $?。这个命令代表 上个命令的退出状态,或函数的返回值。例如:
### diffchangeFile代表某个路径
open -a Xcode ${diffchangeFile}
###$?    上个命令的退出状态,或函数的返回值。
###例子1 :
###ls 命令没有找到匹配的结果. 所以返回2  $? 就是2
###
if [  $? != 0 ]
then
echo "*********打开失败**********"
open -a Xcode ${diffchangeFile}
fi

5.2 for 循环

for循环语法格式如下

# loop 是变量
for loop in 1 2 3 4 5
do
    echo "The value is: $loop"
done

#或者
array_name=("大神" "慢走" "请留步")

for loop in ${array_name[@]};
do
   echo "*************${loop}****************"
done

5.3 while循环

while 语法格式如下

int=1
while(( $int<=5 ))
do
    echo $int
    let "int++"
done
  • 其中 (())是括号内部表示的
  • let 是shell中定义的命令。使用方式如下

自加操作:let no++

自减操作:let no--

简写形式 let no+=10,let no-=20

通常还可以使用 while做命令读取。 read 命令类似C 语言中scanf等待输入。例如:

echo '按下 <CTRL-D> 退出'
echo -n '输入你最喜欢的网站名: '
while read FILM
do
    echo "是的!$FILM 是一个好网站"
done
#<CTRL-D> <CTRL-D> 为退出操作

5.4 case

类似于 switch 功能.语法如下

casein
模式1)
   command1
   command2
   ...
   commandN
   ;;
模式2)
   command1
   command2
   ...
   commandN
   ;;
esac

举例说明

echo '输入 1 到 4 之间的数字:'
echo '你输入的数字为:'
read aNum
case $aNum in
   1)  echo '你选择了 1'
   ;;
   2)  echo '你选择了 2'
   ;;
   3)  echo '你选择了 3'
   ;;
   4)  echo '你选择了 4'
   ;;
   *)  echo '你没有输入 1 到 4 之间的数字'
   ;;
esac

六、函数

函数定义和使用

shell 函数 定义方式如下

函数名(){
    
}

直接填写函数名可以调用函。不过如果函数没有对应的实现。会被当成命令来执行

shell 函数没有形参的概念。但是如果想获得函数的入参 可以通过 $n 获取。还能通过重定向 < 方式获得的

#定义函数
funWithParam(){
    echo "第一个参数为 $1 !"
    echo "第二个参数为 $2 !"
    echo "第十个参数为 $10 !"
    echo "第十个参数为 ${10} !"
    echo "第十一个参数为 ${11} !"
    echo "参数总数有 $# 个!"
    echo "作为一个字符串输出所有参数 $* !"
}
#调用函数
funWithParam 1 2 3 4 5 6 7 8 9 34 73

还有几个特殊字符用来处理参数

$#	传递到脚本的参数个数
$*	以一个单字符串显示所有向脚本传递的参数
?	脚本运行的当前进程ID号
$!	后台运行的最后一个进程的ID号
$@	与$*相同,但是使用时加引号,并在引号中返回每个参数。
$-	显示Shell使用的当前选项,与set命令功能相同。
$?	显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。

参考资料

http://www.runoob.com/linux/linux-shell.html https://www.cnblogs.com/OldJack/p/6602666.html