Shell编程

(1)
输出命令:echo [选项] [输出内容]
-e 支持反斜线控制的字符转换
 
接收键盘输入:read [选项] [变量名]
-p “提示信息”:在等待read输入时,输出提示信息
-t 秒数: read命令会一直等待用户输入,使用此选项可以指定等待时间
-n 字符数:  read命令只接受指定的字符数,就会执行
-s: 隐藏输入的数据,适用于机密信息的输入
例: 
#!/bin/bash
read -t 30 -p "Please input your name: " name
# 提示“请输入姓名”并等待 30 秒,把用户的输入保存入变量 name 中
echo "Name is $name "
read -s -t 30 -p "Please enter your age: " age
# 年龄是隐私,所以我们用“ -s ”选项隐藏输入
echo -e " "
echo "Age is $age "
read -n 1 -t 30 -p "Please select your gender[M/F]: " gender
# 使用“ -n 1 ”选项只接收一个输入字符就会执行(都不用输入回车)
echo -e " "
echo "Sex is $gender"

(2)脚本
1.开头需加:#!/bin/bash
2.给脚本赋予权限:chmod 755 hello.sh
3.执行:
  绝对路径执行:./hello.sh
  通过bash:bash hello.sh
注:windows编辑的sh在linux无法执行,转换格式:dos2unix hello.sh
 
(3)bash基本功能
1.历史命令:history [选项] [历史命令保存文件]
-c 清空历史命令
-w 把缓存中的历史命令修历史命令保存文件 ~/.bash_history
历史命令默认保存1000条,可在环境变量配置文件/etc/profile中修改

2.命令别名:
设定命令别名:alias 别名='原命令'
查询命令别名:alias
让别名永久生效:vi /root/.bashrc
删除别名:unalias 别名

3.快捷键
剪切光标前的内容:ctrl + u 
剪切光标后的内容:ctrl + k 
粘贴u,k内容:ctrl + y 
把光标移到命令开头:ctrl + a
把光标移到命令结尾:ctrl + e
强行终止命令:ctrl + c 
清屏:ctrl + l 
搜索:ctrl + r
退出当前终端:ctrl + d 
暂停,放入后台:ctrl + z 
暂停屏幕输出:ctrl + s 
回复屏幕输出:ctrl + q 

4.输出重定向

a.标准输入输出:
设备    设备文件名    文件描述符    类型
键盘    /dev/stdin        0        标准输入
显示器    /dev/sdtout        1        标准输出
显示器    /dev/sdterr        2        标准错误输出

b.输出重定向:
类型                    符号                作用
标准输出重定向        命令>文件            以覆盖的方式,把命令的正确输出写入指定文件或设备中
                    命令>>文件            以追加的方式,把命令的正确输出写入指定文件或设备中
标准错误输出重定向    错误命令 2>文件        以覆盖的方式,把命令的错误输出写入指定文件或设备中
                    错误命令 2>>文件    以追加的方式,把命令的错误输出写入指定文件或设备中

c、正确输出和错误输出同时保存
命令 > 文件 2>&1          以覆盖的方式,把正确输出和错误输出都保存到同一个文件中
命令 >> 文件 2>&1         以追加的方式,把正确输出和错误输出都保存到同一个文件中    
命令 &> 文件             以覆盖的方式,把正确输出和错误输出都保存到同一个文件中    
命令 &>> 文件             以追加的方式,把正确输出和错误输出都保存到同一个文件中    
命令 >> 文件1 2>> 文件2    把正确的输出追加到文件1,把错误的输出追加到文件2中

丢弃:命令 &>/dev/null

5.输入重定向:命令<文件
统计:wc [选项] [文件名]
-c 统计字节数
-w 统计单词数
-l 统计行数
结束:ctrl+d
例:wc < a.log

6.多命令顺序执行
多命令执行符    格式                作用
;                命令1 ; 命令2        多命令顺序执行,之间没有逻辑联系
&&                命令1 && 命令2        逻辑与 当命令1正确执行,则命令2才会执行;当命令1执行不正确,命令2不会执行
||                命令1 || 命令2        逻辑或 当命令1执行不正确,则命令2才会执行;当命令1正确执行,则命令2不会执行

例:命令 && echo yes || echo no

7.管道符:
命令1的正确输出作为命令2的操作对象:命令1 | 命令2 

显示包含关键字的行:grep [选项] '搜索内容' 文件名
-i 忽略大小写
-n 输出行号
-v 反向查找
--color=auto 搜索出的关键字用颜色显示

8.通配符
? 匹配一个任意字符
* 匹配0个或多个任意字符,也就是可以匹配任何内容
[] 匹配中括号任意一个字符。例如:[abc]代表一定匹配一个字符
[-] 匹配中括号任意一个字符,-代表范围。例如:[a-z]代表匹配一个小写字母
[^]逻辑非,表示匹配不是中括号内的一个字符。例如:[^0-9]代表匹配一个不是数字的字符

(3)bash的变量
1.用户自定义变量
范围:在当前shell中生效
    设置变量:变量名=变量值(等号左右不可有空格)
    查看变量:echo $变量名
    查看所有变量:set
    删除变量:unset 变量名
注:$(命令) 可以执行命令
$(( 数值运算 )) 可以进行运算

2.环境变量:保存和操作系统环境相关的数据
范围:在当前shell和子shell中生效,若写入配置文件则所有shell生效
    申明变量:export 变量名=变量值
    查询变量:env
    删除变量:unset 变量名

常见环境变量:
PATH:系统查找命令路径
例:PATH="$PATH":/root/sh 变量叠加

PS1:定义系统提示符

3.位置参数变量:向脚本传递参数,变量名不能自定义
位置参数变量          作 用
    $n            n为数字,$0代表命令本身,$1-${10}代表第1到第10个参数
    $*            代表命令行中所有的参数,$*把所有的参数看成一个整体
    $@            代表命令行中所有的参数,不过$@把每个参数区分对待
    $#            代表命令行中所有参数的个数

例:
#!/bin/bash
num1=$1 #$1代表传入的第一个参数 不可加分号
num2=$2 #$2代表传入的第二个参数
sum=$(($num1 + $num2))
# 变量 sum 的和是 num1 加 num2
echo $sum
#执行 ./sum.sh 3 7 
#得到 10

4.预定义变量:Bsah中已经定义好的变量
预定义变量          作 用
    $?            最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行;如果这个变量的值为非0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确
    $$            当前进程的进程号(PID)
    $!            后台运行的最后一个进程的进程号(PID)

5.数值运算
声明变量类型:declare [+/-][选项] 变量名
- 给变量设定类型属性
+ 取消变量的类型属性
-i 将变量声明为整数型(integer)
-x 将变量声明为环境变量
-p 显示指定变量的被声明的类型
例:
    cc=$(($aa+$bb)) #常用
    cc=$[ $aa+$bb ]
    cc=$(expr $aa + $bb)#“ + ”号左右两侧必须有空格
    declare -i cc=$aa+$bb

6.运算符
优先级(越大越高)  运算符              说明
13                  -, +            单目负、单目正
12                  !, ~              逻辑非、按位取反或补码
11                  * , / , %          乘、除、取模
10                  +, -              加、减
9                      << , >>          按位左移、按位右移
8                  < =, > =, < , >     小于或等于、大于或等于、小于、大于
7                      == , !=          等于、不等于
6                          &              按位与
5                          ^              按位异或
4                          |              按位或
3                          &&          逻辑与
2                          ||          逻辑或
1    =,+=,-=,*=,/=,%=,&=, ^=,|=, <<=, >>=    赋值、运算且赋值
例:
#虽然乘和除的优先级高于加,但是通过小括号可以调整运算优先级
 aa=$(( (11+3)*3/2 ))
#14 不能被 3 整除,余数是 2
 bb=$(( 14%3 ))
# 逻辑与运算只有想与的两边都是 1 ,与的结果才是 1 ,否则与的结果是0
 cc=$(( 1 && 0 ))

    
7.变量测试与内容替换
通过y判断x:
变量置换方式  变量y没有设置          变量y为空值          变量y设置值
x=${y-新值}          x=新值              x为空                  x=$y
x=${y:-新值}          x=新值              x=新值              x=$y
x=${y+新值}          x为空                  x=新值              x=新值
x=${y:+新值}          x为空                  x为空                  x=新值
x=${y=新值}        x=新值,y=新值        x为空,y值不变        x=$y,y值不变
x=${y:=新值}    x=新值,y=新值        x=新值,y=新值        x=$y,y值不变
x=${y?新值} 新值输出到标准错误输出(屏幕) x为空                x=$y
x=${y:?新值} 新值输出到标准错误输出 新值输出到标准错误输出  x=$y

例:
测试x=${y-新值}
# 删除变量 y
unset y
# 进行测试
x=${y-new}
# 因为变量 y 不存在,所以 x=new
echo $x
# 给变量 y 赋值为空
y=""
# 进行测试
x=${y-new}
echo $x
# 给变量 y 赋值
y=old
# 进行测试
x=${y-new}
#old
echo $x

(4)环境变量配置文件(后面覆盖前面)
1.配置文件即时生效:source 配置文件  或  . 配置文件
2.定义:环境变量配置文件中主要是定义对系统的操作环境生效的系统默认环境变量,比如PATH、HISTSIZE、PS1、HOSTNAME等默认环境变量。
3.位置
全局生效:
    /etc/profile
    /etc/profile.d/*.sh
    /etc/bashrc
当前用户生效:
    ~/.bash_profile
    ~/.bashrc
4.作用
/etc/profile的作用:
    USER变量:
    LOGNAME变量:
    MAIL变量:
    PATH变量:
    HOSTNAME变量:
    HISTSIZE变量:
    umask:
    调用/etc/profile.d/*.sh文件
~/.bash_profile的作用:
    调用了~/.bashrc文件。
    在PATH变量后面加入了“:$HOME/bin”这个目录
~/.bashrc的作用:
    定义默认别名
    调用/etc/bashrc
/etc/bashrc的作用:
    PS1变量
    umask
    PATH变量
    调用/etc/profile.d/*.sh文件
5.其他:
~/.bash_logout :注销时生效的环境变量配置文件
~/bash_history :历史命令

6.Shell登录信息
本地终端欢迎信息:vim /etc/issue
转义符      作 用
d      显示当前系统日期
s      显示操作系统名称
l      显示登录的终端号,这个比较常用。
m      显示硬件体系结构,如i386、i686等
     显示主机名
o      显示域名
     显示内核版本
     显示当前系统时间
u      显示当前登录用户的序列号

远程终端欢迎信息:vim /etc/issue.net
    转义符在/etc/issue.net文件中不能使用,是否显示此欢迎信息,由ssh的配置文件/etc/ssh/sshd_config决定,加入“Banner/etc/issue.net”行才能显示(记得重启SSH服务:service sshd restart)
    
登陆后欢迎信息:/etc/motd
    不管是本地登录,还是远程登录,都可以显示此欢迎信息

(5)正则表达式与通配符
正则:在文件中匹配符合条件的字符串,是包含匹配。grep、awk、sed等可以支持。
通配符:匹配符合条件的文件名,是完全匹配。ls、find、cp等可以支持

元字符      作 用
*          前一个字符匹配0次或任意多次。
.          匹配除了换行符外任意一个字符。
^          匹配行首。例如:^hello会匹配以hello开头的行。
$          匹配行尾。例如:hello&会匹配以hello结尾的行。
[]        匹配中括号中指定的任意一个字符,只匹配一个字符。
[^]        匹配除中括号的字符以外的任意一个字符。例:[^0-9] 
         转义符。用于取消讲特殊符号的含义取消。
{n}    表示其前面的字符恰好出现n次。例:[0-9]{4} 匹配4位数字
{n,}    其前面的字符出现不小于n次。例:[0-9]{2,} 两位及以上
{n,m} 表示其前面的字符至少出现n次,最多出现m次。例如: [a-z]{6,8} 匹配6到8位的小写字母

(6)条件判断
1、按照文件类型进行判断
测试选项        作 用
-b 文件        判断该文件是否存在,并且是否为块设备文件(是块设备文件为真)
-c文件        判断该文件是否存在,并且是否为字符设备文件(是字符设备文件为真)
-d 文件        判断该文件是否存在,并且是否为目录文件(是目录为真)
-e 文件        判断该文件是否存在(存在为真)
-f 文件        判断该文件是否存在,并且是否为普通文件(是普通文件为真)
-L 文件        判断该文件是否存在,并且是否为符号链接文件(是符号链接文件为真)
-p 文件        判断该文件是否存在,并且是否为管道文件(是管道文件为真)
-s 文件        判断该文件是否存在,并且是否为非空(非空为真)
-S 文件        判断该文件是否存在,并且是否为套接字文件(是套接字文件
为真)

两种判断格式(echo $?)
    test -e /root/install.log  
    [ -e /root/install.log ] 

# 第一个判断命令如果正确执行,则打印“ yes ”,否则打
印“ no ”
    [ -d /root ] && echo "yes" || echo "no"

2、按照文件权限进行判断
测试选项            作 用
-r 文件        判断该文件是否存在,并且是否该文件拥有读权限(有读权限为真)
-w文件        判断该文件是否存在,并且是否该文件拥有写权限(有写权限为真)
-x 文件        判断该文件是否存在,并且是否该文件拥有执行权限(有执行权限为真)
-u 文件        判断该文件是否存在,并且是否该文件拥有SUID权限(有SUID权限为真)
-g 文件        判断该文件是否存在,并且是否该文件拥有SGID权限(有SGID权限为真)
-k 文件        判断该文件是否存在,并且是否该文件拥有SBit权限(有SBit权限为真)

3、两个文件之间进行比较
测试选项                    作 用
文件1 -nt 文件2        判断文件1的修改时间是否比文件2的新(如果新则为真)
文件1 -ot 文件2        判断文件1的修改时间是否比文件2的旧(如果旧则为真)
文件1 -ef 文件2        判断文件1是否和文件2的Inode号一致,可以理解为两个
文件是否为同一个文件。这个判断用于判断硬链接是很好的方法

4、两个整数之间比较
测试选项                作 用
整数1 -eq 整数2        判断整数1是否和整数2相等(相等为真)
整数1 -ne 整数2        判断整数1是否和整数2不相等(不相等位置)
整数1 -gt 整数2        判断整数1是否大于整数2(大于为真)
整数1 -lt 整数2        判断整数1是否小于整数2(小于位置)
整数1 -ge 整数2        判断整数1是否大于等于整数2(大于等于为真)
整数1 -le 整数2        判断整数1是否小于等于整数2(小于等于为真)

5、字符串的判断
测试选项                    作 用
-z 字符串        判断字符串是否为空(为空返回真)
-n 字符串        判断字符串是否为非空(非空返回真)    
字串1 ==字串2    判断字符串1是否和字符串2相等(相等返回真)
字串1 != 字串2    判断字符串1是否和字符串2不相等(不相等返回真)

6、多重条件判断
测试选项            作 用
判断1 -a 判断2    逻辑与,判断1和判断2都成立,最终的结果才为真
判断1 -o 判断2    逻辑或,判断1和判断2有一个成立,最终的结果就为真
!判断            逻辑非,使原始的判断式取反

(7)if语句
1、 单分支if条件语句
if [ 条件判断式 ];then
    程序
fi

或者

if [ 条件判断式 ]
then
    程序
fi

注:
if语句使用fi结尾,和一般语言使用大括号结尾不同,后面必须有空格
[ 条件判断式 ]就是使用test命令判断,所以中括号和条件判断式之间必须有空格
then后面跟符合条件之后执行的程序,可以放在[]之后,用“;”分割。也可以换行写入,就不需要“;”了

2、双分支if条件语句
if [ 条件判断式 ]
then
    条件成立时,执行的程序
else
    条件不成立时,执行的另一个程序
fi

3、 多分支if条件语句
if [ 条件判断式1 ]
then
    当条件判断式1成立时,执行程序1
elif [ 条件判断式2 ]
then
    当条件判断式2成立时,执行程序2
else
    当所有条件都不成立时,最后执行此程序
fi


例:判断apache是否启动
#!/bin/bash
# Author: shenchao (E-mail: shenchao@lampbrother.net)
port=$(nmap -sT 192.168.1.156 | grep tcp | grep http | awk '{print
$2}')
#使用nmap命令扫描服务器,并截取apache服务的状态,赋予变量port
if [ "$port" == "open" ]
then
echo “$(date) httpd is ok!” >> /tmp/autostart-acc.log
else
/etc/rc.d/init.d/httpd start &>/dev/null
echo "$(date) restart httpd !!" >> /tmp/autostart-err.log
fi


(8)case语句
case $变量名 in 
    "值1")
        如果变量的值等于值1,则执行程序1
    ;;
    "值2")
        如果变量的值等于值2,则执行程序2
    ;;
    *)
        如果变量的值都不是以上的值,则执行此程序
    ;;
esac

(9)for循环
for 变量 in 值1 值2 值3…
do
    程序
done

或者

for (( 初始值;循环控制条件;变量变化 ))
do
    程序
done

(10)while循环:条件循环。只要条件判断式成立,循环就会一直继续,直到条件判断式不成立,循环才会停止。这就和for的固定循环不太一样了。
while [ 条件判断式 ]
do
    程序
done

(11)until循环:和while循环相反,until循环时只要条件判断式不成立则进行循环,并执行循环程序。一旦循环条件成立,则终止循环。
until [ 条件判断式 ]
do
    程序
done
   

原文地址:https://www.cnblogs.com/quanzhiguo/p/7157427.html