Shell编程基础

  1. Linux shell简介
  1. Shell概述
Shell是linux的命令语言程序设计语言,shell是linux外壳,linux内核,通过外壳协议,来操作内核。在cat/etc/shells目录下。

  1. Shell基本格式
vi helloworld.sh ##代码写在普通文本中,通常以.sh结尾
#!/bin/bash ##表示用Shell解析器的类型
echo "hello world" ##注释也可以写在这里

  1. Shell执行方式
sh方式或者bash方式
sh helloworld.sh
bash helloworld.sh
source方式或者 . 方式
使Shell程序文件并依次执行文件中所有语句
. helloworld.sh ##注意 . 和脚本之间是有空格的
source helloworld.sh
直接执行该脚本文件
执行之前需要更改文件的执行权限
./helloworld.sh ##相对路径方式
/home/linux/helloworld.sh ##绝对路径方式

  1. Shell注释
单行注释:
#
多行注释:
:<<!
内容
!


  1. Shell基本语法
  1. 变量
  1. 系统变量
$PWD $SHELL $USERE $HOME

  1. 自定义变量
变量=值 ##等号两侧不能有空格,变量名称一般习惯大写
$变量名 ##使用变量
PS:
引号在引用变量时的区别:
如果是单引号,则引号当中的任何东西都当做字符串 ,即特殊字符会被脱意
如果是双引号, 那么$ABC 能打印出变量的值
总结:
单引号:
1、单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的
2、单引号字串中不能出现单引号(对单引号使用转义符后也不行)
双引号:
1、双引号里可以有变量
2、双引号里可以出现转义字符
unset 变量名 ##撤销变量
readonly 变量名='值' ##静态变量,只读,不能撤销
export A="A in a.sh"
##export关键字,意味着把变量提升为shell进程中的全局环境变量可供其他的shell子程序使用

总结:
1 、a.sh中直接调用 b.sh,会让 b.sh 在A所在的 bash进程的“子进程”空间中执行
2 、而子进程空间只能访问父进程中用 export 定义的变量
3 、一个 shell进程无法将自己定义的变量提升到父进程空间中去
4 、source 或者 “. ”号执行脚本时,会让脚本在调用者所在的 shell进程空间中执行

反引号赋值
a=`ls -l /root/bin` ##反引号,运行里面的命令,并把结果返回给变量a
a=$(ls -l /root/bin)


  1. 特殊变量
$? 表示上一个命令退出的状态码
$$ 表示当前进程编号
$0 表示当前脚本名称
$n 表示 n 位置的输入参数(n 代表数字,n>=1 )
$# 表示参数的个数,常用于循环
$* [email protected] 都表示参数列表
重点:$*和[email protected]的区别:

$* 和 [email protected] 都表示传递给函数或脚本的所有参数

不被双引号" " 包含时 ==== $* 和 [email protected] 都以$1 $2 „ $n 的形式组成参数列表
当它们被双引号" " 包含时 ====
"$*" 会将所有的参数作为一个整体,以"$1 $2 „ $n" 的形式组成一个整串;
"[email protected]" 会将各个参数分开,以"$1" "$2" „ "$n"

Shell编程基础

  1. 运算符
  1. 算数运算符
expr,运算符间有空格,*需要转义\*,不适用浮点数
(()),不适用浮点数
$[ ],不适用浮点数
let,设置变量的方式,不适用浮点数
eg:first=1
second=2
let third=first+second
echo ${third}
bc计算器,可以将echo和bc结合使用:
eg:echo "1.212*3" | bc ## 简单浮点运算
echo "scale=2;3/8" | bc ##将输出结果设置为 2 位
echo "obase=2;127" | bc ##输出运算结果的二进制
echo "obase=10;ibase=2;101111111" | bc ##将二进制转十进制
echo "10^10" | bc ##求幂指数
echo "sqrt(100)" | bc ##开平方

  1. 关系运算符
三元运算符:条件 && 是 || 否
运算符
等同运算符
说明
-eq
=
检测两个数是否相等,相等返回true
-ne
!=
检测两个数是否相等,不相等返回true
-ge
>=
检测锁边的数是否大于等于右边的,如果是,返回true
-gt
>
检测锁边的数是否大于右边的,如果是,返回true
-le
<=
检测锁边的数是否小于等于右边的,如果是,返回true
-lt
<
检测锁边的数是否小于右边的,如果是,返回true

  1. 逻辑运算符
运算符
等同运算符
说明
非运算,表达式为 true 则返回 false,否则返回 true
-a
&&
与运算,两个表达式都为 true 才返回 true
-o
||
或运算,有一个表达式为 true 则返回 true

  1. 字符串运算符
运算符
说明
=
检测两个字符串是否相等,相等返回 true
!=
检测两个字符串是否相等,不相等返回 true
-z
检测字符串长度是否为 0,为 0 返回 true
-n
检测字符串长度是否为 0,不为 0 返回 true
str
检测字符串是否为空,不为空返回 true

  1. 文件运算符
Shell编程基础
Shell编程基础
  1. 流程控制
  1. if
if condition
then
statements
[elif condition
then statements. ..]
[else
statements ]
fi
  1. while
Shell编程基础
Shell编程基础
  1. case
case $1 in
start)
echo "starting"
;;
stop)
echo "stoping"
;;
*)
echo "Usage: {start|stop}"
esac
  1. for
for 变量 in 列表
do
command
……
done
for N in 1 2 3; do echo $N; done
for N in {1..3}; do echo $N; done
for ((i=0; i<=2; i++)); do echo "welcome $i times"; done
  1. util
until expression ##expression为false执行,直到为true
do
command
……
done



  1. 跳出循环
break:终止循环
continue:结束 本次循环开始下一次循环

  1. 数组
array_name=(value1 ... valuen) ##定义数组
${array_name[index]} ##读取数组元素
echo ${!mingxing[@]} ##获取数组下标
echo ${mingxing[*]}echo ${mingxing[@]} ##输出数组所有元素
unset mingxing[0] ##删除第一个元素
echo ${#mingxing[*]}echo ${#mingxing[@]}##获取数组长度
遍历数组:
#!/bin/bash
IP=(192.168.1.1 192.168.1.2 192.168.1.3)
# 第一种方式
for ((i=0;i<${#IP[*]};i++))
do
echo ${IP[$i]}
done

#第二种方式
for ip in ${IP[*]}
do
echo $ip
done
  1. 函数使用
[[email protected] bin]# vi i.sh
#!/bin/sh
hello(){
echo "`date +%Y-%m-%d`"
# return 2
}
hello
echo “huangbo”
# echo $?
A="mazhonghua"
echo $A
PS:注意:
1、必须在调用函数地方之前,先声明函数,shell 脚本是逐行运行。不会像其它语言一样先预编译
2、函数返回值,只能通过$? 系统变量获得,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return 后跟数值 n(0-255)


  1. 函数参数
[[email protected] bin]# vi funcWithParam.sh
#!/bin/bash
# filename=funcWithParam
funcWithParam(){
echo "第一个参数为 $1 !"
echo "第二个参数为 $2 !"
echo "第十个参数为 $10 !"
echo "第十个参数为 ${10} !"
echo "第十一个参数为 ${11} !"
echo "参数总数有 $# 个!"
echo "作为一个字符串输出所有参数 $* !"
}
funcWithParam 1 2 3 4 5 6 7 8 9 34 73


  1. 跨脚本调用函数

. /home/linux/bin/base.sh ## 引入脚本



写脚本注意事项:
1、开头加解释器: #!/bin/bash,和注释说明。
2、命名建议规则:变量名大写、局部变量小写,函数名小写,名字体现出实际作用。
3、默认变量是全局的,在函数中变量 local 指定为局部变量,避免污染其他作用域。
4、set -e 遇到执行非 0 时退出脚本, set -x 打印执行过程。
5、写脚本一定先测试再到生产上。