Shell简介:Shell本身是用C语言编写的程序,它是用户使用Unix/Linux的桥梁, Shell既是一种命令语言,又是一种程序设计语言,
作为命令语言,它交互式地解释和执行用户输入的命令;
作为程序设计语言,它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和分支。
Shell两种执行命令的方式
交互式:(Interactive):解释执行用户的命令,用户输入一条命令,Shell就解释执行一条。
批量处理(Batch):用户事先写一个Shell脚本(Script),其中有很多命令,让Shell一次把这些命令执行完,而不必一条一条地敲命令。
几种常见的Shell
Shell是一种脚本语言,那么,就必须有解释器来执行这些脚本。我们常说有多少种Shell, 其实说的是Shell脚本解释器.
1) bash<=bash 是Linux标准默认的Shell,本文的Shell都是基于bash环境。
2)sh
3)ash
4)csh
5)ksh
第一个Shell脚本
打开脚本编辑器,新建一个文件,扩展名为sh(sh代表shell),扩展名并不影响脚本执行,但一般都以sh做扩展名。
编写Shell
#!/bin/bash <="#!"是一个约定的标记,告诉系统这个脚本需要什么解释器来执行,即使用哪一种Shell echo "Hello World !" #<=echo命令用于向窗口输出文本
运行Shell
两种方式运行Shell
1.作为可执行程序
sh ./Shell.sh
2.作为解释器参数
/bin/sh Shell.sh
===================================================================================================================
Shell语法汇总
Shell注释
#以#开头的就是注释 #单引号双引号的区别 # #单引号字符串的限制: #单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的; #单引号字串中不能出现单引号(对单引号使用转义符后也不行)。 # #双引号的优点: #双引号里可以有变量 #双引号里可以出现转义字符 # #所以一般都用双引号!!!
①Shell变量
运行Shell时,会同时存在三种变量。
1)局部变量
仅在当前shell实例中有效,其他shell的启动的程序不能访问局部变量。
2)环境变量
所有的程序,包括shell启动程序,都能访问环境变量。必要的时候shell脚本也可以定义环境变量。
3)shell变量
由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行。
1.局部变量
定义变量时,变量名不加美元符号($)!!!如:
variableName=“value”
注意:变量名和符号之间不能有空格。
变量名命名规则:
a.首个字符必须为字母(a-z,A-Z); b.中间不能有空格,可以使用下划线(_); c.不能使用标点符号; d.不能使用bash里的关键字(可以使用help命令查看保留关键字)
使用一个定义过的变量名要在前面加美元符号($),如
your_name=“Steven” echo $your_name echo ${your_name} #变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界(推荐给所有变量加上花括号)
已定义过的变量可以重写定义
your_name=“Tony” echo ${your_name}
算数运算符
原生bash不支持简单的数学运算,但是可以通过其他命令来实现,expr是一款表达式计算工具,使用它能完成表达式的求值操作。
#两点注意: #表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2,这与我们熟悉的大多数编程语言不一样。 #完整的表达式要被 `` 包含,注意这个字符不是常用的单引号,在 Esc 键下边 #+ :加法 举例:`expr $a + $b` 结果为30 #- :减法 举例:`expr $a - $b` 结果为10 #* :乘法 举例:`expr $a * $b` 结果为20 #/ :除法 举例:`expr $b / $q` 结果为2 #% :取余 举例:`expr $b % $q` 结果为0 #= :赋值 举例:a=$b 将变量b的值赋给a #== :相等 用于比较两个数字,相同则返回True 举例:[ $a == $b ] 返回false. #!= :不相等 用于比较两个数字,不相同则返回True 举例:[ $a != $b ] 返回true. #注意:条件表达式要放在方括号之间,并且要有空格!!! #例如 [$a==$b] 是错误的,必须写成 [ $a == $b ]。 a=6 b=2 c=`expr $a + $b` echo "c:$c" d=`expr $a - $b` echo "d:$d" e=`expr $a * $b` echo "e:$e" f=`expr $a / $b` echo "f:$f" g=`expr $a % $b` echo "g:$g" h=$f echo "h:$h" if [ $a == $b ] then echo "a is equal to b" else echo "a is not equal to b" fi
关系运算符
#关系运算符 #关系运算符只支持数字,不支持字符串,除非字符串的值是数字。 #-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
布尔运算符
#布尔运算符 #! 非运算,表达式为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
字符串运算符
#字符串运算符 #= 检测两个数字是否相等,相等则返回true 举例 [ $a = $b ] 返回false #!= 检测两个数字是否相等,不相等则返回true 举例 [ $a != $b ] 返回true #-z 检测字符串长度是否为0,为0返回true. 举例 [ -z $a ] 返回false #-n 检测字符串长度是否为0,不为0返回true. 举例 [ -n $a ] 返回true #str 检测字符串长度是否为空,不为空返回true. 举例 [ str $a ] 返回true
字符串使用实例
#字符串拼接 your_name="Tony" greeting="hello,"$your_name" !" greeting_2="hello, ${your_name} !" echo $greeting $greeting_2 #字符串长度获取 string="abcd" echo $string #提取子字符串 string="alibaba is a great company" echo ${string:1:4} #输出liba
文件运算符
#文件运算符 #-r file 检测文件是否可读,如果是则返回true [-r $file] #-w file 检测文件是否可写,如果是则返回true [-w $file] #-s file 检测文件是否为空,如果不为空返回true [-s $file] #-e file 检测文件是否存在,如果是则返回true [-e $file]
文件测试运算符列表 举例
1 .-b file 检测文件是否是块设备文件,如果是,则返回true。 [-b $file]返回false
2.-c file 检测文件是否是字符设备文件,如果是,则返回true。 [-c $file]返回false
3.-d file 检测文件是否是目录,如果是,则返回true。 [-d $file]返回false
4.-f file 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回true。 [-f $file]返回true
5.-g file 检测文件是否设置了SGID位,如果是,则返回true. [-g $file]返回true
6.-k file 检测文件是否设置了粘着位( Sticky Bit),如果是,则返回 true. [-k $file]返回true
7.-p file 检测文件是否是具名管道,如果是,则返回true。 [-p $file]返回true
8.-u file 检测文件是否设置了SUID位,如果是,则返回true。 [-u $file]返回true
9-r file 检测文件是否可读,如果是,则返回true. [-r $file]返回true
10.-w file 检测文件是否可写,如果是,则返回true. [-w $file]返回true
11.-x file 检测文件是否可执行,如果是,则返回true [-x $file]返回true
12.-s file 检测文件是否为空(文件大小是否大于0),不为空返回tue。 [-s $file]返回true
13.-e file 检测文件(包括目录)是否存在,如果是,则返回true. [-e $file]返回true
③Shell函数定义
1.函数格式
function_name (){
list of commands
[ return value ]
}
如果你愿意,也可以在函数名前加上关键字 function
function getAge(){ age=10 return $age } echo "调用getAge函数" getAge echo "getAge返回值是:$?" #注意: 获取返回的返回值,使用$?来获取;
函数返回值,可以显式增加return语句;如果不加,会将最后一条命令运行结果作为返回值。
Shell 函数返回值只能是整数,一般用来表示函数执行成功与否,0表示成功,其他表示失败。如果return其他数据,比如字符串,会得到报错提示:“numeric argument required”。要求数值参数。
如果一定要让函数返回字符串,那么可以先定义一个变量,用来接收函数的计算结果,脚本在需要的时候访问这个变量来获得函数返回值。
调用函数只需要给出函数名,不需要加括号。
#1.无返回值,无参数 print(){ echo "1.无返回值,无参数" } print #2.有返回值,无参数 #如果你愿意,也可以在函数名前加上关键字 function function getAge(){ age=10 return $age } echo "调用getAge函数" #调用函数只需要给出函数名,不需要加括号。 getAge echo "getAge返回值是:$?" #注意: 获取返回的返回值,使用$?来获取; #函数返回值,可以显式增加return语句;如果不加,会将最后一条命令运行结果作为返回值。Shell 函数返回值只能是整数,一般用来表示函数执行成功与否,0表示成功,其他表示失败。如果return其他数据,比如字符串,会得到报错提示:“numeric argument required”。要求数值参数。 #如果一定要让函数返回字符串,那么可以先定义一个变量,用来接收函数的计算结果,脚本在需要的时候访问这个变量来获得函数返回值。 function getSum(){ a=10 b=20 return $(($a+$b)) } getSum echo "getSum返回值是:$?"
//参数调用
在Shell中,调用函数时可以向其传递参数。在函数内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数…
注意:$10不能获取第十个参数,获取十个参数需要${10}。当n>=10时,需要使用${n}来获取参数。
#参数调用 echo "---参数调用---" #在Shell中,调用函数时可以向其传递参数。在函数内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数… #注意:$10不能获取第十个参数,获取十个参数需要${10}。当n>=10时,需要使用${n}来获取参数。 function postParams() { echo "The value of the first parameter is $1 !" echo "The value of the second parameter is $2 !" echo "The value of the tenth parameter is $10 !" echo "The value of the tenth parameter is ${10} !" echo "The value of the eleventh parameter is ${11} !" echo "The amount of the parameters is $# !" # 参数个数 echo "The content of the parameters is $* !" # 传递给函数的所有参数 } #调用函数 postParams 1 2 3 4 5 6 7 8 9 10 11 12 #输出结果如下 #The value of the first parameter is 1 ! #The value of the second parameter is 2 ! #The value of the tenth parameter is 10 ! #The value of the tenth parameter is 10 ! #The value of the eleventh parameter is 11 ! #The amount of the parameters is 12 ! #The content of the parameters is 1 2 3 4 5 6 7 8 9 10 11 12 !
④Shell判断语句
#001-If语句
#Shell 有三种if … else 语句:
#a if … fi 语句;
#b if … else … fi 语句;
#c if … elif … else … fi 语句。
#a=b a=10 b=10 if [ $a == $b ] then echo "a is equal to b" fi #a!=b a=10 b=20 if [ $a == $b ] then echo "a is equal to b" else echo "a is not equal to b" fi #a和b 比较 a=30 b=10 if [ $a == $b ] then echo "a is equal to b" elif [ $a -gt $b ] then echo "a is greater than b" elif [ $a -lt $b ] then echo "a is less than b" else echo "none pf the condition met" fi
#002-Case语句
#case工作方式:
#1.取值后面必须为关键字 in
#2.每一模式必须以右括号结束。
#3.取值可以为变量或常数
#4.匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;;
#;; 与其他语言中的 break 类似,意思是跳到整个 case 语句的最后。
#1.取值后面必须为关键字 in #2.每一模式必须以右括号结束。 #3.取值可以为变量或常数 #4.匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;; #;; 与其他语言中的 break 类似,意思是跳到整个 case 语句的最后。 echo 'Please input a number between 1 to 4' echo 'Your number is :c' read num #read 读取用户输入的数字 case $num in 1) echo 'You select 1' ;; 2) echo 'You select 2' ;; 3) echo 'You select 3' ;; 4) echo 'YOu select 4' ;; *) echo 'You do not select a num between 1 to 4' ;; esac #退出Case语句
⑤Shell循环语句
#001-For循环
#语法格式 #for 变量 in 列表 #do #command #done for loop in 1 2 3 4 5 do echo "The value is : $loop" done
#002-While循环
#while command #do #Statement(s) to be executed if command is true #done COUNTER=0 while [ $COUNTER -lt 5 ] do COUNTER=`expr $COUNTER + 1` echo $COUNTER done
#003-until循环
#until command #do #Statement(s) to be executed until command is true #done a=0 until [ ! $a -lt 10 ] do echo $a a=`expr $a + 1` done
#004-Shell 跳出循环
#break 和 continue #break #break命令允许跳出所有循环(终止执行后面的所有循环)。 #在嵌套循环中,break 命令后面还可以跟一个整数,表示跳出第几层循环。例如: break n #表示跳出第 n 层循环。 #break n 跳到指定的循环,如果n不指定 , 默认跳到最大的循环.,继续执行最大循环里面的语句;如果n大于最大循环,条件一旦成立则跳出最大循环。 #continue #continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。
⑥Shell设置启动参数
echo "~~~~~~~~~~~~选择打包方式(输入序号)~~~~~~~~~~~~~~~" echo " 1 adHoc" echo " 2 AppStore" echo " 3 Enterprise" # 读取用户输入并存到变量里 read parameter sleep 0.5 method="$parameter" # 判读用户是否有输入 if [ -n "$method" ] then if [ "$method" = "1" ] then #adhoc脚本 echo "您输入了参数1" elif [ "$method" = "2" ] then #appstore脚本 echo "您输入了参数2" elif [ "$method" = "3" ] then #企业打包脚本 echo "您输入了参数3" else echo "参数无效" exit 1 fi fi
Shell打包常见问题:
①xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Deve (Xcode目录被篡改)
以上错误是因为安装了 xcode , 但并不是系统默认的位置, 所以可以使用以下命令把 xcode 的路径修改为你安装的位置即可
$sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
红色部分就是你安装的 xcode 的自定义路径.