shell编程基础

  • shell使用户与Linux操作系统之间沟通的桥梁,用户可以通过输入命令执行,又可以利用shell脚本编程去运行
  • Linux shell种类
    • bourne shell(usr/bin/sh或/bin/sh)
    • bourne again shell(/bin/bash)
    • C shell(/usr/bin/csh)
    • K shell(/usr/bin/ksh)
    • shell for root(/sbin/sh)
  • 不同的shell语言的语法有所不同,一般不能交换使用,最常用的shell是bash,也就是bourne again shell(/bin/bash).bash由于易用和免费,是大多数操作系统默认的shell环境
  • 简单来说,shell是一个整体的概念,shell编程与shell脚本统称为shell编程,shell命令是shell编程底层具体的语句和实现方法

shell脚本及Hello World

  • shell脚本编程注意事项:
    • shell脚本名称命名一般为英文的大写、小写
    • 不能使用特殊符号、空格来命名
    • shell脚本后缀以.sh结尾
    • 不建议shell命名为纯数字,一般以脚本功能命名
    • shell脚本内容首行需要以#!/bin/bash开头
    • shell脚本中变量名称尽量使用大写字母,字母间不可以使用"-",可以使用"_"
    • shell脚本变量名称不能以数字、特殊符号开头
  • 第一个shell编程脚本,脚本名称为first_shell.sh
    • !bin/bash:固定格式,定义该脚本所使用的的shell类型

    • # This is my First shell:#表示注释,没有任何意义,shell不会解析
    • echo "Hello World":shell脚本主命令,执行该脚本所呈现的内容
#!bin/bash
# This is my First shell
echo "Hello World"
  • shell脚本编写完毕,如果运行该脚本,运行用户需要有执行权限,可以使用chomd o+x first_shell.sh赋予可执行权限.然后./first_shell.sh执行即可,还可以使用命令/bin/sh first_shell.sh直接运行脚本,不需要执行权限,最终执行显示效果一样

shell编程之变量

  • shell属于非类型的解释型语言,在使用变量时不像C++、JAVA语言编程时需要事先声明变量,shell给一个变量赋值,实际上就是定义了变量,在Linux支持的所有shell中,都可以用赋值符合"="为变量赋值,shell为弱类型语言,定义变量不需要声明变量类型,如果在使用时需要明确变量的类型,可以使用declare指定类型,declare常见参数如下:
    • +/-:"-"可以用来指定变量的属性,"+"为取消变量所设的属性
    • -f:仅显示函数
    • r:将变量设置为只读
    • x:指定的变量会变为环境变量,可供shell以外的程序来使用
    • i:指定类型为数值,字符串或运算式
  • shell编程中变量分为3种:系统变量、环境变量、用户变量,其中系统变量在对参数判断和命令返回值判断时使用,而环境变量则主要是在程序运行时需要设置,用户变量又称为局部变量,多使用在shell脚本内部或者临时局部
  • shell变量名在定义时,首个字符必须为(a-z,A-Z),不能以数字开头,中间不能有空格,可以使用下划线"_",不能使用"-",也不能使用标点符号等
  • 例如定义变量A=apple,定义这样一个变量,A为变量名,apple是变量的值,变量名有规范格式,变量的值可以随意指定.变量定义完成,如需要引用变量,可以使用$A
#!bin/bash
A=apple
echo "这个变量的值是$A"

# 执行该脚本,显示的结果为-------这个变量的值是apple
  • shell常见的系统变量、环境变量、用户变量
    1. 系统变量
      • $0:当前脚本名称
      • $n:当前脚本的第n个参数
      • $*:当前脚本的所有参数(不包括程序本身)
      • $#:当前脚本的参数个数(不包括程序本身)
      • $?:命令或程序执行完后的状态,返回0表示执行成功
      • $$:程序本身的PID号
    2. 环境变量
      • PATH:命令所示路径,以冒号为分割
      • HOME:打印用户家目录
      • SHELL:显示当前shell类型
      • USER:打印当前用户名
      • ID:打印当前用户ID信息
      • PWD:显示当前所在路径
      • TERM:打印当前终端类型
      • HOSTNAME:显示当前主机名
    3. 用户变量
      • A=apple

if条件语句

  • if条件判断语句,通常以if开头,fi结尾.也可以加入else或者elif进行多条件的判断,if表达式如下
if (表达式)
    语句1
else
    语句2
fi
  • 比较两个整数大小
#!/bin/bash
NUM=100
if (( $NUM>4 ));then
    echo "数字$NUM大于4"
else
    echo "数字$NUM小于4"
fi
  • 判断系统目录是否存在
#!/bin/bash
if [ ! -d /data/0326 ];then
    mkdir -p /data/0326
else
    echo '目录或文件已存在'
fi
  • if常见的判断逻辑运算符

    • -f:判断文件是否存在,例如if[-f filename]
    • -d:判断目录是否存在,例如if[-d dir]
    • -eq:等于,应用于整型比较,即equal
    • -ne:不等于,应用于整型比较,即not equal
    • -lt:小于,应用于整型比较,即letter
    • -gt:大于,应用于整型比较,即greater
    • -le:小于等于,应用于整型比较
    • -ge:大于等于,应用于整型比较
    • -a:双方都成立(and),用法为逻辑表达式-a
    • -o:单方成立(or),用法为逻辑表达式-o
    • -z:空字符串
    • ||:单方成立
    • &&:双方都成立表达式
  • 多条件判断

#!/bin/bash
scores=$1
if [[ $scores -eq 100 ]];then
    echo "very good"
elif [[ $scores -gt 85 ]];then
    echo "good"
elif [[ $scores -gt 60 ]];then
    echo "pass"
else
    echo "no pass"
fi

if判断括号区别

  • ():用于多个命令组、命令替换、初始化数组
  • (()):整数扩展、运算符、重定义变量值、算术运算比较
  • []:bash内部命令,"["与test是等同的,正则字符范围、引用数组元素编号,不支持"+"、"-"、"*"、"/"数学运算符,逻辑测试使用-a、-o
  • [[]]:bash程序语言的关键字,不是一个命令,[[]]结构比[]结构更加通用,不支持"+"、"-"、"*"、"/"数学运算符,逻辑测试使用&&、||
  • {}:主要用于命令集合或者范围,例如mkdir -p /data{1..10}

MySQL数据库备份脚本

#!/bin/bash
# auto backup mysql
BAK_DIR=/data/backup/mysql/`date +%F`
MYSQLDB=test
NYSQLPW=123456
MYSQLUSR=root
# must use root user run scripts 必须使用root用户运行,$UID为系统变量
if [ $UID -ne 0 ];then
    echo "This script must use the root user "
    sleep 2
    exit 0
fi
# Define DIRand mkdir 判断目录是否存在,不存在则创建
if [ ! -d $BAK_DIR ];then
    mkdir -p $BAK_DIR
fi
# Use mysqldump backup Databases
/usr/local/mysql/bin/mysqldump -u$MYSQLUSR -p$NYSQLPW -d $MYSQLDB > $BAK_DIR/db.sql
echo "The mysql backup successfully"

for循环语句

  • for循环语句主要用于对某个数据域进行循环读取、对文件进行遍历,通常用于循环某个文件或者列表.其语法格式以for...do开头,done结尾
for var in (表达式);do
    语句
done
  • 循环打印1-100数字,seq表示列出数据范围
#!/bin/bash
for num in `seq 1 10`;do
    echo $num
done
  • for循环求1-100的和
#!/bin/bash
SUM=0
for (( i=1;i<=100;i++ ));do
    SUM=`expr $i + $SUM`
done
echo $SUM
  • 对系统日志文件进行打包
#!/bin/bash
for i in `find /var/log -type f -name '*.log'`;do
    tar zcf `date +%F`.tar.gz $i
done
  • for循环批量远程主机文件传输
#!/bin/bash
for i in `seq 100 200`;do
    scp -r /tmp/file.txt root@10.0.0.$i:/data
done
  • for循环批量远程主机执行命令
#!/bin/bash
for i in `seq 100 200`;do
    ssh -l root 10.0.0.$i 'ls /opt'
done
  • for循环打印10s等待提示
#!/bin/bash
for (( i=1;i<=10;i++ ));do
    echo -ne "\033[32m-\033[0m"
    sleep 1
done
echo

while循环语句

  • while循环语句与for循环功能类似,主要用于对某个数据域进行循环读取、对文件进行遍历,通常用于循环某个文件或者列表,满足循环条件会一直循环,不满足则退出循环,其语法格式以while...do开头,done结尾
while (表达式);do
    语句
done
  • 循环打印文件中的域名
cat test.txt 
www.baidu.com
www.ali.com
www.qq.com

vim pra.sh
#!/bin/bash
while read line;do
    echo $line
done < test.txt
  • while无限每秒输出Hello World
#!/bin/bash
while sleep 1;do
    echo -e "\033[32mHello World.\033[0m"
done
  • 循环打印1-100数字,expr用于逻辑运算
#!/bin/bash
i=1
while (( i<=100 ));do
    echo $i
    i=`expr $i + 1`
done
  • while循环求1-100的和
#!/bin/bash
NUM=1
SUM=0
while (( NUM<=100 ));do
    SUM=`expr $NUM + $SUM`
    (( NUM++ ))
done
echo $SUM
  • while逐行读取文件
#!/bin/bash
while read line;do
    echo $line
done < /root/test/test.txt
  • 每5秒判断/etc/passwd是否被非法修改
#!/bin/bash
FILE_PATH=/etc/passwd
while true;do
    echo "The Time is `date +%F`"
    OLD=`md5sum $FILE_PATH|cut -d" " -f 1`
    sleep 5
    NEW=`md5sum $FILE_PATH|cut -d" " -f 1`
    if [[ $OLD != $NEW ]];then
        echo "The $FILE_PATH has been modified"
    fi
done
  • 每10s循环判断用户是否登录系统
#!/bin/bash
USER=test
while true;do
    echo "The Time is `date +%F`"
    sleep 10
    NUM = `who|grep "$USER"|wc -l`
    if [[ $NUM -ge 1 ]];then
        echo "The $USER is login in system"
    fi
done

case选择语句

  • case选择语句主要用于对多个选择条件进行匹配输出,与if...elif语句结构类似,通常用于脚本传递输出参数,打印出输出结果及内容,其语法格式以case...in开头,esac结尾
#!/bin/bash
case $1 in
    Pattern1)
    语句1
    ;;
    Pattern2)
    语句2
    ;;
    Pattern3)
    语句3
    ;;
esac
  • 打印monitor及archive选择菜单
#!/bin/bash
case $1 in
        monitor)
        monitor_log
        ;;
        archive)
        archiver_log
        ;;
        help)
        echo -e "\033[32mUsage:{$0 monitor |archive |help}\033[0m"
        ;;
        *)
        echo -e "\033[32mUsage:{$0 monitor |archive |help}\033[0m"
esac

select选择语句

  • select选择语句一般用于选择,常用于选择菜单的创建,可以配合PS3来打印菜单的输出信息,其语法格式以select...in do开头,done结尾
select i in (表达式);do
    语句
done
  • 打印操作系统选择
#!/bin/bash
PS3="select system"
select i in Centos Ubuntu Windows;do
    echo "your select system: "$i
done
  • 打印LAMP选择菜单
#!/bin/bash
PS3="select system"
select i in http MySQL PHP quit;do
case $i in
        http)
        echo Test Httpd
        ;;
        MySQL)
        echo Test MySQL
        ;;
        PHP)
        echo Test PHP
        ;;
        quit)
        echo The System exit
        exit
esac
done

shell编程函数

  • shell允许将一组命令集或者语句形成一个可用块,这些块称为shell函数,shell函数的好处在于只需定义一次,后期随时使用,无须在shell脚本中添加重复的语句块,其语法格式为以"function name(){"开头,以"}"结尾
  • shell编程函数默认不能将参数传入()内部,shell函数参数传递在调用函数名称时传递,例如name argv1 argv2
function name(){
    command1
    command2
    ...
}
name argv1 argv2
  • 创建Apache软件安装函数,给函数Apache_install传递参数1
#!/bin/bash
H_FILES=httpd-2.2.31.tar.bz2
HFILES_DIR=httpd-2.2.31
H_PREFIX=/usr/local/apache
H_URL=http://mirrors.cnnic.cn/apache/httpd/
function apache_install(){
if [[ $1 -eq 1 ]];then
    wget -c $H_URL/$H_FILES && tar -xf $H_FILES && cd $HFILES_DIR &&./configure --prefix=$H_PREFIX
    if [[ $? -eq0 ]];then
        make && make install
        echo -e "\n\033[32m---------------------------\033[0m"
        echo -e "\033[32mThe $HFILES_DIR Server Install Success!\033[0m"
    else
        echo -e "\033[32mThe $HFILES_DIR Make or Make install ERROR,Please Check..."
        exit 0
    fi
fi
}
apache_install 1

shell数组编程

  • 数组是相同数据类型的元素按一定顺序排列的集合,把有限个类型相同的变量用一个名字命名,然后用编号区分它们变量的集合,这个名称即为数组名,编号即为下标.Linux shell编程中常用一维数组
  • 数组的设计实际上是为了处理方便,把具有相同类型的若干变量按有序的形式组织起来的一种形式,以减少重复频繁的单独定义
  • 定义数组一般以小括号的方式来定义,数组的值可以随机指定,以下为一维数组的定义、统计、引用和删除
  1. 一维数组的定义及创建
CITY=(
    beijing
    tianjin
    shanghai
)
LAMP=(httpd php php-devel php-mysql mysql mysql-server)
  1. 数组下标一般从0开始,引用数组的方法为
    • echo ${CITY[0]}:引用第一个数组变量
    • echo ${CITY[1]}:引用第二个数组变量
    • echo ${CITY[@]}:显示该数组所有参数
    • echo ${#CITY[@]}:显示该数组参数个数
    • echo ${#CITY[0]}:显示beijing字符长度
    • echo ${CITY[@]:0}:打印所有数组的值
    • echo ${CITY[@]:1}:打印从第二个值开始的所有值
    • echo ${CITY[@]:0:2}:打印第一个值与第二个值
    • echo ${CITY[@]:1:2}:打印第二个值与第三个值
  2. 数组替换操作
    • CITY=([0]=www1 [1]=www2 [2]=www3):数组赋值
    • echo ${CITY[@]/beijing/nanjing}:将数组值beijing替换为nanjing
    • NEWCITY=echo ${CITY[@]/beijing/nanjing}
  3. 数组删除操作
    • unset array[0]:删除数组第一个值
    • unset array[1]:删除数组第二个值
    • unset array:删除整个数组
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335