shell编程企业级实战(2)
Vim配置文件.vimrc
- vim配置文件
if 条件语句
if是最常见的条件判断语句
- 例1:如果不存在/backup目录就创建。
- [root@web-01 /server/tools]# vim 07-01.sh
#!/bin/bas
path=/backup
[ -d $path ] || mkdir $path -p
# 相当于
# :冒号表示什么也不干
if [ -d $path ]
then
:
else
mkdir $path -p
fi
# 或者
[ !-d $path ] && mkdir /backdir -p
# 相当于
if [ !-d $path ]
then
mkdir /backdir -p
if
"07-01.sh" 18L, 248C writte
vim命令:替换:%s#/backup#$path#g- 例2:开发Shell脚本判断系统剩余内存的大小,如果低于100MB就提示内存不足,否则提示内存充足。
- 考查if双分支:
- 分析:
- )提取系统内存。
- )if判断,
- [root@web01 ]# cat 07_02.sh
- #!/bin/bash
- ##############################################################
- # File Name: 07_02.sh
- # Version: V1.
- # Author: pizza
- # Created Time : -- ::
- # Description:
- ##############################################################
- mem=`free -m|awk 'NR==3{print $NF}'`
- if [ $mem -lt ]
- then
- echo "内存严重不足。"
- else
- echo "内存还够"
- fi
- 在第一章的中添加了内存不足发邮件的例子
- 例3:分别使用变量定义、read读入及脚本传参方式实现比较2个整数的大小。
- )变量定义:
- a=
- b=
- )read读入:
- read -p "请输入两个数字:" a b
- )传参:
- 分析:
- 大于 等于 小于
- #!/bin/bash
##############################################################
# File Name: 07-03.sh
# Version: V1.0
# Author: pizza
# Created Time : 2019-03-28 21:20:46
# Description:
##############################################################
# 第一种,传参
a=6
b=7
# 第二种,read
read -p "请输入两个数字" a b
# 第三种,参数
$a=$1
$b=$2
# 判断输入
# 1、判断数字是不是够,判断b是不是空,或者使用$#
# 2、判断是不是整数,利用expr
# 3、- if [ $a -gt $b ]
then
echo "$a>$b"
elif [ $a -lt $b ]
then
echo "$a<$b"
else
echo "$a=$b"
fi- 例4:打印一个菜单如下,当用户选择对应的数字时,就执行对应项的应用。
- .install lamp
- .install lnmp
- .exit
- 第一章已讲解:
- bash内置核心命令read的企业级应用实践
- read企业应用
- [root@web01 scripts]# cat select1.sh
- #!/bin/bash
- cat <<EOF
- .install lamp
- .install lnmp
- .exit
- EOF
- read -p "请选择一个序号(必须是数字):" num
- #.判断是否为整数
- expr + $num &>/dev/null
- if [ $? -ne ]
- then
- echo "Usage:$0 {1|2|3}"
- exit
- fi
- #.判断执行处理
- if [ $num -eq ]
- then
- echo "install lamp..."
- elif [ $num -eq ]
- then
- echo "install lnmp..."
- elif [ $num -eq ]
- then
- echo "bye."
- exit
- else
- echo "Usage:$0 {1|2|3}"
- exit
- fi
Shell函数的知识与实践
函数的作用就是将程序里多次被调用的相同代码组合起来,并为其取个名字。其他所有想重复调用这部分代码的复方都只需要调用这个这个名字就可以了。当需要修稿这部分重复代码的时候,也只需要改变函数内的一份代码即可实现所有的修改,也可以把函数独立写到文件里面,当需要调用的时候,再加载进来。
函数的语法体
- oldboy() {
- echo "I am oldboy."
- }
- function oldgirl {
- echo "I am oldgirl."
- }
- test() {
- echo "Hello world."
- }
- oldboy
- oldgirl
- [root@web-01 ~]# sh test_hanshu.sh
I am oldboy.
I am oldgirl.
Hello world.
[root@web-01 ~]#
向函数传参
- 带参数的函数编写执行
- oldboy() {
- echo "I am $1."
- }
- oldboy oldboy
- 将函数传参转为脚本传参
- oldboy() {
- echo "I am $1."
- }
- oldboy $1
- 函数和执行函数分离
./etc/init.d/function
pizza $1
Shell函数的执行注意事项
企业案例:通过脚本传参的方式,检查Web 网站URL是否正常。
- wget命令:
- --spider 模拟爬虫
- -q 安静访问
- -o /dev/null 不输出
- -T --timeout 超时时间
- -t --tries 重试次数
- [root@web01 ~]# wget --spider -T -q -o /dev/null -t www.baidu.com
- [root@web01 ~]# echo $?
- curl命令:
- -I 看响应头
- -s 安静的 安静模式。不显示进度表或错误信息。使cURL 不反馈信息。
- -o /dev/null 不输出
- -w %{http_code} 返回状态码,200
-m 超时时间- [root@web01 ~]# curl www.baidu.com -s &>/dev/null
- [root@web01 ~]# echo $?
- [root@web01 ~]# curl -I -m -s -w "%{http_code}\n" -o /dev/null www.baidu.com
- 不用函数的实现写法
- #!/bin/sh
- if [ $# -ne ]
- then
- echo $"usage:$0 url"
- exit
- fi
- wget --spider -q -o /dev/null --tries= -T $ #<==-T指定超时时间,这里的$1为脚本的参数。
- if [ $? -eq ]
- then
- echo "$1 is yes."
- else
- echo "$1 is no."
- fi
- 高端专业的函数写法:
- [root@oldboy ~]# cat checkurl.sh
- #!/bin/bash
- ##############################################################
- # File Name: checkurl.sh
- # Version: V1.
- # Author: oldboy
- # Organization: www.oldboyedu.com
- # Created Time : -- ::
- # Description:
- ##############################################################
- usage(){
- echo "Usage:$0 url"
- exit
- }
- checkurl(){
- wget -q -o /dev/null -t -T $
- if [ $? -eq ]
- then
- echo "$1 is ok"
- else
- echo "$1 is fail"
- fi
- }
- main(){
- if [ $# -ne ]
- then
- usage
- fi
- checkurl $
- }
- main $*
- [root@oldboy scripts]# cat 8_5_1.sh
- #!/bin/sh
- function usage() { #<==帮助函数
- echo $"usage:$0 url"
- exit
- }
- function check_url() { #<==检测URL函数。
- wget --spider -q -o /dev/null --tries= -T $ #<==这里的$1就是函数传参。
- if [ $? -eq ]
- then
- echo "$1 is yes."
- else
- echo "$1 is no."
- fi
- }
- function main() { #<==主函数。
- if [ $# -ne ] #<==如果传入的多个参数,则打印帮助函数,提示用户。
- then
- usage
- fi
- check_url $ #<==接收函数的传参,即把结尾的$*传到这里。
- }
- main $* #<==这里的$*就是把命令行接收的所有参数作为函数参数传给函数内部,常用手法。
CASE结构条件句
- 几乎所有的case都可以用if替代
- case "$1" in
- )
- dddd
- ;;
- )
- dddd
- ;;
- *)
- dddd
- esac
- 企业应用:
- 启动脚本
- read 读入 菜单选择。
- 范例9_2:执行shell脚本,打印一个如下的水果菜单:
- .apple
- .pear
- .banana
- .cherry
- 当用户输入对应的数字选择水果的时候,告诉他选择的水果是什么,并给水果单词加上一种颜色(随意),要求用case语句实现。
- 范例9_3:给内容加不同的颜色。
- 内容的颜色用数字表示,范围为30-,每个数字代表一种颜色。代码如下:
- echo -e "\033[30m 黑色字 \033[0m" #<==30m表示黑色字。
- echo -e "\033[31m 红色字 \033[0m" #<==31m表示红色字。
- echo -e "\033[32m 绿色字 \033[0m" #<==32m表示绿色字。
- echo -e "\033[33m 棕色字 \033[0m" #<==33m表示棕色字(brown),和黄色字相近。
- echo -e "\033[34m 蓝色字 \033[0m" #<==34m表示蓝色字。
- echo -e "\033[35m 洋红字 \033[0m" #<==35m表示洋红色字(magenta),和紫色字相近。
- echo -e "\033[36m 蓝绿色 \033[0m" #<==36m表示蓝绿色字(cyan),和浅蓝色字相近。
- echo -e "\033[37m 白色字 \033[0m" #<==37m表示白色字。
- 说明:不同的数字对应的字体颜色,见系统帮助(来源man console_codes命令的结果)。
- 范例9_6: 给输出的字符串加不同的背景颜色。
- 字的背景颜色对应的数字范围为40-,代码如下。
- echo -e "\033[40;37m 黑底白字\033[0m" #<==40m表示黑色背景。
- echo -e "\033[41;37m 红底白字\033[0m" #<==41m表示红色背景。
- echo -e "\033[42;37m 绿底白字\033[0m" #<==42m表示绿色背景。
- echo -e "\033[43;37m 棕底白字\033[0m" #<==43m表示棕色背景(brown),和黄色背景相近。
- echo -e "\033[44;37m 蓝底白字\033[0m" #<==44m表示蓝色背景。
- echo -e "\033[45;37m 洋红底白字\033[0m" #<==45m表示洋红色背景(magenta),和紫色背景相近。
- echo -e "\033[46;37m 蓝绿底白字\033[0m" #<==46m表示蓝绿色背景(cyan),和浅蓝色背景相近。
- echo -e "\033[47;30m 白底黑字\033[0m" #<==47m表示白色背景。
创建case3.sh,定义函数 ,执行函数color $*
创建case4.sh,用.或者source调用函数,打印菜单,输入数字,显示不同颜色的字体- 范例9_10:利用case语句开发Rsync服务启动停止脚本,本例采用case语句以及新的思路来实现。
- 分析:
- 启动:
- rsync --daemon
- 停止:
- pkill rsync
- killall rsync
- kill 进程号 ---->最专业的方法
- /etc/init.d/rsyncd {start|stop|restart}
- case
rsync.sh简单版
- case "$1" in
- start)
- rsync --deamon
- if [ $? -eq ]
- then
- echo "rsync startup ok"
- else
- echo "rsync startup fail"
- fi
- ;;
- stop)
- killall rsync
- if [ $? -eq ]
- then
- echo "rsync stop ok"
- else
- echo "rsync stop fail"
- fi
- ;;
- restart)
- killall rsync && sleep && rsync --deamon
- if [ $? -eq ]
- then
- echo "rsync restart ok"
- else
- echo "rsync restart fail"
- fi
- ;;
- *)
- echo "usage:$0 {start|stop|restart}"
- exit
- esac
升级版
- start(){
- rsync --deamon
- retval=$?
- if [ $retval -eq ]
- then
- echo "rsync startup ok"
- return $retval
- else
- echo "rsync startup fail"
- return $retval
- fi
- }
- stop(){
- killall rsync
- retval=$?
- if [ $? -eq ]
- then
- echo "rsync stop ok"
- , Top
- return $retval
- else
- echo "rsync restart fail"
- return $retval
- fi
- }
- case "$1" in
- start)
- start
- # 为了向外传值
- retval=$?
- ;;
- stop)
- stop
- retval=$?
- ;;
- restart)
- restart
- retval=$?
- ;;
- *)
- echo "usage:$0 {start|stop|restart}"
- exit
- esac
想要使用chkconfig(man ckhconfig),找到这些信息
- RUNLEVEL FILES
- Each service which should be manageable by chkconfig needs two or more commented lines added to its init.d
- script. The first line tells chkconfig what runlevels the service should be started in by default, as well
- as the start and stop priority levels. If the service should not, by default, be started in any runlevels,
- a - should be used in place of the runlevels list. The second line contains a description for the ser‐
- vice, and may be extended across multiple lines with backslash continuation.
- For example, random.init has these three lines:
- # chkconfig: 80 表示在2345这几个启动级别上 启动顺序排20 停止顺序排80
- # description: Saves and restores system entropy pool for \
- # higher quality random number generation.
在脚本首行加入
- #!/bin/bash
- # chkconfig:
- # description: rsync start stop and restart
将脚本移动到/etc/init.d/下,并添加执行权限,添加到chkconfig中才能使用
- [root@web- /server/tools]# mv /etc/init.d/rsync_up.sh /etc/init.d/rsyncd
- [root@web- /server/tools]# chmod +x /etc/init.d/rsyncd
- [root@web- /server/tools]# chkconfig --list rsyncd
- Note: This output shows SysV services only and does not include native
- systemd services. SysV configuration data might be overridden by native
- systemd configuration.
- If you want to list systemd services use 'systemctl list-unit-files'.
- To see services enabled on particular target use
- 'systemctl list-dependencies [target]'.
- service rsyncd supports chkconfig, but is not referenced in any runlevel (run 'chkconfig --add rsyncd')
- [root@web- /server/tools]# chkconfig --add rsyncd
- [root@web- /server/tools]# chkconfig --list rsyncd
- Note: This output shows SysV services only and does not include native
- systemd services. SysV configuration data might be overridden by native
- systemd configuration.
- If you want to list systemd services use 'systemctl list-unit-files'.
- To see services enabled on particular target use
- 'systemctl list-dependencies [target]'.
- rsyncd :off :off :on :on :on :on :off
更好一些,调用了系统函数,action。并优化了重复停止的输出
- #!/bin/bash
- # chkconfig:
- # description: rsync start stop and restart
- ##############################################################
- # File Name: syncd.sh
- # Version: V1.
- # Author: pizza
- # Created Time : -- ::
- # Description:
- ##############################################################
- . /etc/init.d/functions
- start(){
- rsync --deamon
- retval=$?
- if [ $retval -eq ]
- then
- action "rsync startup ok" /bin/true
- return $retval
- else
- action "rsync startup fail" /bin/false
- return $retval
- fi
- }
- , Top
- return $retval
- fi
- }
- case "$1" in
- start)
- start
- # 我了向外传值
- retval=$?
- ;;
- stop)
- stop
- retval=$?
- ;;
- restart)
- restart
- retval=$?
- ;;
- *)
- echo "usage:$0 {start|stop|restart}"
- exit
- esac
开发和系统媲美的脚本
跟完善的查看企业实践题第11题-制作MySQL脚本
- ,- Bot
- #!/bin/bash
- # chkconfig:
- # description: rsync start stop and restart
- ##############################################################
- # File Name: syncd.sh
- # Version: V1.
- # Author: pizza
- # Created Time : -- ::
- # Description:
- ##############################################################
- # 定义锁文件
- lockfile=/var/lock/subsys/rsyncd
- # 定义变量,指定rsyncd的的pid,是需要自己rsync的conf中去创建
- #[root@web- /server/tools]# vim /etc/rsyncd.conf
- #pid file=/var/run/rsyncd.pid
- srsync_pid_file_path=/var/run/rsyncd.pid
- . /etc/init.d/functions
- start(){
- rsync --deamon
- retval=$?
- if [ $retval -eq ]
- then
- action "rsync startup ok" /bin/true
- touch $lockfile
- return $retval
- else
- action "rsync startup fail" /bin/false
- return $retval
- fi
- }
- stop(){
- # 为了在重复停止操作的时候,不提示,将其扔到黑洞
- if test -s "$rsyncd_pid_file_path"
- then
- rsyncd_pid=`cat $rsyncd_pid_file_path`
- # 判断进程号是不是真实存在
- if (kill - $rsyncd_pid &>/dev/null)
- then
- kill $rsyncd_pid
- retval=$?
- if [ $? -eq ]
- then
- action "rsync stop ok" /bin/true
- rm -f $lockfile
- return $retval
- else
- action "rsync stop fail" /bin/false
- return $retval
- fi
- else
- echo "rsyncd process is not exist."
- return
- fi
- else
- echo "$srsync_pid_file_path is not exits,or rsyncd doesnot start"
- fi
- }
- restart(){
- killall rsync && sleep && rsync --deamon
- retval=$?
- if [ $? -eq ]
- then
- action "rsync restart ok" /bin/true
- return $retval
- else
- action "rsync restart fail" /bin/false
- return $retval
- fi
- }
- case "$1" in
- start)
- start
- # 我了向外传值
- retval=$?
- ;;
- stop)
- stop
- retval=$?
- ;;
- restart)
- restart
- retval=$?
- ;;
- *)
- echo "usage:$0 {start|stop|restart}"
- exit
- esac
case总结
1、case语句和if条件句的使用性
case语句比较适合变量较少且为固定的数字或者字符串集合的情况(非不确定内容,如范围)
2、if和case的常用应用场景
case只要写服务的启动脚本,一般情况下,传参不同且具有少量的字符串,其使用范围较窄
if就是取值判断、比较,应用比case更广,几乎所有的case语句都可以用if条件语句实现。
3、case语句的特点和优势
它相当于多分支的if/elif/else语句,但是case语句的优势是更规范。易读
while循环
循环语句命令常用于重复执行一条指令或一组指令,直到条件不满足停止,Shell脚本语言的循环语句常见的有while、until、for以及select循环语句。 while循环语句主要用来重复执行一组命令或语句,在企业实际应用中,常用于守护进程或持续运行的程序,除此以外,大多数循环都会用后文即将讲解 的for循环语句。
- while true
- do
- uptime >> /tmp/uptime.log
- sleep # 暂停2s
- usleep # 微秒
- done
脚本进程管理命令
后台运行 &、nohup、screen(运维人员)
为什么要用后台运行,防止你在执行重要命令的时候,网络宕机
进程管理的其他常见命令
范例1:请使用while循环对下面的脚本进行修改,是的当执行脚本时,每次执行完脚本后,不退出脚本,而是提示用户输入
- while true
- do
- read -p "请输入两个数字:" a b
- if [ -z $b ]
- then
- echo "请输入两个数字"
- continue
- fi
- expr + $a + $b &>/dev/null
- if [ $? -ne ]
- then
- echo "请输入两个数字"
- continue
- fi
- echo "a+b=$(($a+$b))"
- done
范例2:猜数字游戏。首先让系统随机生成一个数字,给这个数字定一个范围(1-60),让用户输入猜的数字,对输入进行判断,如果不符合要求,就给予高或低的提示,猜对后则给出猜对用的次数,请用while语句实现。
提示:可以赋予一个猜水果的价格游戏。
- 、给数字定范围(-)
- RANDOM随机数,它的范围是0-
- [root@web- /server/tools]# echo $RANDOM
- 为随机数取模。控制在1-
- [root@web- /server/tools]# echo $((RANDOM%))
- 、用户输入数字
- read -p “请输入数字:” num
- 、对比,直到正确才推出
- while
- 4、代码:
- random="$(($RANDOM%60))"
- #做计数
- count=
- echo $random
- while true
- do
- read -p "请输入数字:" num
- ((count++))
- if [[ $num -lt $random ]]
- then
- echo "低了"
- continue
- elif [[ $num -gt $random ]]
- then
- echo "高了"
- continue
- elif [[ $num -eq $random ]]
- then
- echo "恭喜你,猜对了,一共猜了$count次"
- exit
- else
- echo "请输入数字"
- fi
- done
- 还可以加入函数,其他的限制内判断,使脚本更完善
范例3:分析Apache访问日志(access_2010-12-8.log),把日志中每行的访问字节数对应字段数字相加,计算出总的访问量。给出实现程序,请用while循环实现。(3分钟)
- 方式1:在while循环结尾done通过输入重定向指定读取的文件。
- while read line
- do
- cmd
- done<FILE
- 方式2:使用cat读取文件内容,然后通过管道进入while循环处理。
- cat FILE_PATH|while read line
- do
- cmd
- done
- 方式3:采用exec读取文件后,然后进入while循环处理。
- exec <FILE
- sum=
- while read line
- do
- cmd
- done
体验
- while read line
- do
- echo $line
- sleep
- done < ./while_01.sh
- ~
- ~
- "while_readline.sh" [New] 13L, 320C written
- [root@web- /server/tools]# sh while_readline.sh
- #!/bin/bash
- ##############################################################
- # File Name: while_01.sh
- # Version: V1.
- # Author: pizza
- # Created Time : -- ::
- # Description:
- ##############################################################
- while true
- do
- uptime >> /tmp/uptime.log
- sleep # 暂停2s
- usleep # 微秒
- done
体验2
- [root@web- /server/tools]# seq >>num.log
- 脚本
- sum=
- while read line
- do
- ((sum+=line))
- done<./num.log
- echo $sum
- 执行
- [root@web- /server/tools]# sh while_num_add.sh
答案
- sum=
- awk '{print $10}' access_2010--.log |grep -v -|while read line
- do
- ((sum+=line))
- done
- echo sum
- # 已经计算了,但是最后的结果是0
- # 这是因为执行了子shell
- # 使用下面的方法可以成功输出
- sum=
- awk '{print $10}' access_2010--.log |grep -v - > any_sum.log
- do
- ((sum+=line))
- done<./any_sum.log
- echo sum
小结
1、while循环的特长是执行守护进程,以及实现我们希望循环不退出持续执行的应用
擅长用于频率小于1分钟循环处理,其他的while循环几乎都可以被for以及定时任务crond替代
2、if、for最常用,然后是while(守护进程),case(服务启动脚本)
Shell脚本中各个语句的使用场景
1、条件表达式,用于简短的条件判断及输出(文件是否存在,字符串是否为空)
2、if取值判断,多用于不同值数量较少的情况
3、for正常的循环应用处理,最常用
4、while多用于守护进程,无限循环(要加sleep,usleep,控制pinlv)应用
5、case 多用于服务启动脚本,打印菜单可用select语句,不过很少用,都用cat的here文档方法替代
6、函数用途主要指编码逻辑清晰,减少重复语句开发
for循环
for循环语句和while循环语句类似,但for循环语句主要用于执行次数有限的循环,而不是用于守护进程以及无限循环。for循环语句常见的语法有两种, 下面将在不同的语法中对for循环语句进行详尽的讲解。
..
- 范例1:用for循环竖向打印1、、、、5共5个数字。
- 范例2:通过开发脚本实现仅设置sshd rsyslog crond network sysstat服务开机自启动。
- 范例3:计算从1加到100之和。
- 范例4:在Linux下批量修改文件名,将文件名中的“_finished”去掉。
- 准备测试数据,如下。
- [root@oldboy test]# mkdir /oldboy -p
- [root@oldboy test]# cd /oldboy
- [root@oldboy oldboy]# touch stu_102999_1_finished.jpg stu_102999_2_finished.jpg stu_102999_3_finished.jpg
- [root@oldboy oldboy]# touch stu_102999_4_finished.jpg stu_102999_5_finished.jpg
- [root@oldboy oldboy]# ls -l
- 总用量
- -rw-r--r-- root root 9月 : stu_102999_1_finished.jpg
- -rw-r--r-- root root 9月 : stu_102999_2_finished.jpg
- -rw-r--r-- root root 9月 : stu_102999_3_finished.jpg
- -rw-r--r-- root root 9月 : stu_102999_4_finished.jpg
- -rw-r--r-- root root 9月 : stu_102999_5_finished.jpg
- ls *.jpg|awk -F "_finished" '{print "mv",$0,$1$2}'|bash
- rename "_finished" "" *.jpg
- for file in `ls ./*.jpg`
- do
- mv $file `echo ${file/_finished/}`
- done
范例1答案
- for n in 或者 {1..5} 或者seq 5
- do
- echo $n
- done
- echo "---------"
- for ((i=;i<=;i++))
- do
- echo $i
- done
- "for_printnum.sh" [New] 18L, 350C written
- [root@web- /server/scripts]# sh for_printnum.sh
- ---------
范例2答案
- for name in sshd rsyslog crond network sysstat
- do
- echo "chkconfig $name on"
- done
- 相当于在命令行执行
[root@web-01 /server/scripts]# chkconfig |grep 3:on |awk '{print "chkconfig",$1,"off"}'|bash
范例3
- 、for循环
- 、while循环
- 、算法
范例4
- 、mv $file 'echo ${file/_finished/}'
- 、不用for循环
- [root@web- /server/scripts]# ls *.jpg|awk -F "_finished" '{print $0,$1$2}'
- 、rename from to file
- rename _finished "" *.jpg
循环控制语句break、continue、exit、return
在上述命令中,break、continue在条件语句及循环语句(for、while、if等)中用于控制程序的走向,
而exit则用于终止所有语句并退出当前脚本,除此之外,exit还可以返回上一次程序或命令的执行状态值给当前Shell;
return类似exit,只不过return仅用于在函数内部返回函数执行的状态值。
- break n 如果省略n表示跳出整个循环,n 表示跳出循环的层数
- continue n 如果省略n表示跳过本次循环,忽略本次循环的剩余代码,进入循环的下一次循环。n 表示退到第n层继续循环
- exit n 退出当前shell程序,n为上一次程序执行的状态返回值。n也可以省略,再下一个shell里可通过$?接收exit n的n值
- return n 用于在函数里,作为函数的返回值,用于判断函数执行是否正确。再下一个shell里可通过$?接收exit n的n值
Shell编程数组应用实践
为什么会产生shell数组
通常在开发Shell脚本时,我们定义变量采用的形式为a=1;b=2;c=3,可如果有多个变量呢?这时再一个一个定义很费劲,并且要是有多个不确定的变量内容,也难以进行变量定义,此外,快速读取不同变量的值也是一件很痛苦的事情,于是数组就诞生了,它就是为了解决上述问题而来的。
什么是Shell数组
如果读者有过其他语言的编程经历,那么想必会熟悉数组的概念。简单地说,Shell的数组就是把有限个元素(变量或字符内容)用一个名字命名,然后用编号对它们进行区分的元素集合。这个名字就称为数组名,用于区分不同内容的编号就称为数组下标。组成数组的各个元素(变量)称为数组的元素,有时也称为下标变量。
有了Shell数组后,就可以用相同名字引用一系列变量及变量值,并通过数字(索引)来识别使用它们。在许多场合,使用数组可以缩短和简化程序开发。
数组的本质还是变量,是特殊的变量形式
array=(1 2 3 4 5)
- Shell数组的定义*****
- 方法1:推荐,用小括号把变量值括起来赋值给数组变量,中间用空格分割
- array=(one two three four)
- 方法2:用小括号把变量值括起来,同时采用键值对的形式赋值
- array=([]=one []=two []=three []=four)
- 方法3:通过分别定义数组变量的方式
- [root@web01 ~]# array[]=one
- [root@web01 ~]# array[]=two
- [root@web01 ~]# array[]=three
- [root@web01 ~]# array[]=four
- [root@web01 ~]# echo ${array[@]}
- one two three four
- 方法4:命令的结果放到数组里,推荐。动态定义数组变量,使用命令的输出结果作为数组的内容
- array=(`ls /server/scripts`)
- 说明:还可以使用declare -a array来定义数组类型,但是比较少这样用。
- 操作数组元素
- 打印单个数组元素用${数组名[下标]},当未指定数组下标时,数组的下标是从0开始。
- 使用*或者@可以得到整个数组内容。
- 用${#数组名[@或*]}可以得到数组长度,这和前文讲解的变量子串知识是一样的,因为数组也是变量,只不过是特殊的变量,因此也适合变量的子串替换等知识。
- 读取数组内容:*****
- [root@web01 ~]# array=( )
- [root@web01 ~]# echo ${array[]}
- [root@web01 ~]# echo ${array[]}
- [root@web01 ~]# echo ${array[]}
- [root@web01 ~]# echo ${array[]}
- [root@web01 ~]# echo ${array[]}
- [root@web01 ~]# echo ${array[]}
- [root@web01 ~]# echo ${array[*]}
- [root@web01 ~]# echo ${array[@]}
- [root@web01 ~]# echo ${#array[@]}
- [root@web01 ~]# echo ${#array[*]}
- 给数组增加内容:
- [root@web01 ~]# array[]=oldboy <==增加下标为5的数组元素。
- [root@web01 ~]# echo ${#array[*]}
- [root@web01 ~]# echo ${array[*]}
- oldboy
- 删除数组元素:
- [root@web01 ~]# unset array[]
- [root@web01 ~]# echo ${array[*]}
- oldboy
- [root@web01 ~]# unset array[]
- [root@web01 ~]# echo ${array[*]}
- oldboy
- 数组赋值:
- [root@web- /server/scripts]# array[]=
- [root@web- /server/scripts]# echo ${array[*]}
- 数组的删除:
- 因为数组本质上还是变量,因此可通过“unset 数组[下标]”清除相应的数组元素,
- 如果不带下标,表示清除整个数组的所有数据。
- [root@web- /server/scripts]# unset array[] 删除单个元素
- [root@web- /server/scripts]# echo ${array[*]}
- [root@web- /server/scripts]# unset array 删除整个数组
- [root@web- /server/scripts]# echo ${array[*]} 没有数据输出了
- 数组内容的截取和替换:
- 这里和前文变量子串的替换是一样的,因为数组是特殊的变量
- [root@web- /server/scripts]# echo ${array[*]::} 从下表为1的元素截取3个元素
- 替换 和sed命令,和变量子字符串的替换 很像,是一样的
- [root@web- /server/scripts]# echo ${array[*]//}
- [root@web- /server/scripts]# echo ${array[*]} 该操作不会改变原数组,要改变请参考赋值修改
- 数组也是变量,因此也适合于前面讲解过的变量的子串处理的功能应用。
- 数组的其他相关知识通过man bash然后搜Arrays来了解。
- 数组元素部分内容的删除如下:
- [root@oldboy data]# array=(one two three four five)
- [root@oldboy data]# echo ${array[@]}
- one two three four five
- [root@oldboy data]# echo ${array[@]#o*} #<==从左边开始匹配最短的,并删除。
- ne two three four five
- [root@oldboy data]# echo ${array1[@]##o*} #<==从左边开始匹配最长的,并删除。
- two three four five
- [root@oldboy data]# echo ${array[@]%f*} #<==从右边开始匹配最短的,并删除。
- one two three
- [root@oldboy data]# echo ${array[@]%%f*} #<==从右边开始匹配最长的,并删除。
- one two three
- 使用for循环打印数组元素
- array=( )
- for n in ${array[*]}
- do
- echo $n
- done
- echo =====================
- #i为数组下标
- for ((i=;i<${#array[*]};i++))
- do
- echo ${array[i]}
- done
- array=([]=one []=two []=three)
- array[]=a;array[]=b;array[]=c
- array=($(命令))
- 或
- array=(`命令`)
shell数组企业面试题
1、利用bash for循环打印下面这句话中字母数不大于6的单词(某企业面试真题)。
I am pizza teacher welcome to luffy training class
- array=(I am oldboy teacher welcome to oldboy training class)
- for word in ${array[*]}
#或者
#for ((i=0;i<=${array[*];i++}))- do
- if [ ${#word} -lt ]
# if [ ${#array[i]} -lt 6 ]- then
- echo $word
# echo array[i]- fi
- done
- 第十四章 编程规范
- 第十五章 脚本调试
- 第十六章 vim配置
- 第十七章 trap
- 第十八章 expect
- 第十九章 企业案例实战
- 第十九章
- 企业面试题1:
- 分析:
- 、获取随机小写字符。
- echo $RANDOM$(date +%N)|md5sum|tr "[0-9]" "a-z"|cut -c -
- 、for循环
- 企业面试题3:
- 、..
- [root@db03 ~]# seq -w
- [root@db03 ~]# echo ${..}
- -bash: ${..}: bad substitution
- [root@db03 ~]# echo {..}
- 、echo $RANDOM|md5sum|cut -
- 、for循环批量设置用户和密码。
- 企业面试题4:
- 、如何判断机器是否是活的。
- ping 10.0.0.53 -c -W 有返回。
- nmap -sP 10.0.0.0/
- .for循环
- #!/bin/sh
- CMD="nmap -sP"
- Ip="10.0.0.0/24"
- $CMD $Ip|awk '/Nmap scan report for/ {print $NF}'
- http://blog.51cto.com/oldboy/1632876
- ,,,,,,
shell编程企业级实战(2)的更多相关文章
- shell编程企业级实战
如何才能学好Shell编程 为什么要学习shell编程 Shell是Linux底层核心 Linux运维工作常用工具 自动化运维必备基础课程 学好shell编程所需Linux基础 熟练使用vim编辑器 ...
- Shell编程(week4_day3)--技术流ken
本节内容 1. shell流程控制 2. for语句 3. while语句 4. break和continue语句 5. case语句 6. shell编程高级实战 shell流程控制 流程控制是改变 ...
- Shell编程、part3
本节内容 1. shell流程控制 2. for语句 3. while语句 4. break和continue语句 5. case语句 6. shell编程高级实战 shell流程控制 流程控制是改变 ...
- Shell编程(3)
1. shell流程控制 2. for语句 3. while语句 4. break和continue语句 5. case语句 6. shell编程高级实战 shell流程控制 流程控制是改变程序运行顺 ...
- Shell编程实战
Shell编程实战 为什么要学习Shell编程 Shell脚本语言是实现Linux/Unix系统管理及自动化运维所必须的重要工具,Linux系统的底层以及基础应用软件的核心大都涉及Shell脚本的 ...
- shell编程系列26--大型脚本工具开发实战
shell编程系列26--大型脚本工具开发实战 大型脚本工具开发实战 拆分脚本功能,抽象函数 .function get_all_group 返回进程组列表字符串 .function get_all_ ...
- shell编程系列25--shell操作数据库实战之备份MySQL数据,并通过FTP将其传输到远端主机
shell编程系列25--shell操作数据库实战之备份MySQL数据,并通过FTP将其传输到远端主机 备份mysql中的库或者表 mysqldump 常用参数详解: -u 用户名 -p 密码 -h ...
- shell编程系列24--shell操作数据库实战之利用shell脚本将文本数据导入到mysql中
shell编程系列24--shell操作数据库实战之利用shell脚本将文本数据导入到mysql中 利用shell脚本将文本数据导入到mysql中 需求1:处理文本中的数据,将文本中的数据插入到mys ...
- shell编程系列23--shell操作数据库实战之mysql命令参数详解
shell编程系列23--shell操作数据库实战之mysql命令参数详解 mysql命令参数详解 -u 用户名 -p 用户密码 -h 服务器ip地址 -D 连接的数据库 -N 不输出列信息 -B 使 ...
随机推荐
- kubernetes 客户端KubeClient使用及常用api
KubeClient是kubernetes 的C#语言客户端简单易用,KubeClient是.NET Core(目标netstandard1.4)的可扩展Kubernetes API客户端, gith ...
- 深入介绍Java中的锁[原理、锁优化、CAS、AQS]
1.为什么要用锁? 锁-是为了解决并发操作引起的脏读.数据不一致的问题. 2.锁实现的基本原理 2.1.volatile Java编程语言允许线程访问共享变量, 为了确保共享变量能被准确和一致地更新, ...
- mysql性能优化之数据库级别优化--优化sql语句
一 优化SELECT语句 1.1 WHERE子句优化 本文暂时只讨论可以处理WHERE子句的优化,下面的一些实例使用SELECT语句,但是相同的优化同样适用DELETE和UPDATE语句中的WHER ...
- GROUP BY你都不会!ROLLUP,CUBE,GROUPPING详解
Group By Group By 谁不会啊?这不是最简单的吗?越是简单的东西,我们越会忽略掉他,因为我们不愿意再去深入了解它. 1 小时 SQL 极速入门(一) 1 小时 SQL 极速入门(二) 1 ...
- 自学python的日记分享
2019.4.22登记 课堂笔记 2019.4.8 在windows环境下,用python写出第一个程序“hello world” print("Hello World!!!") ...
- 我所不知道的Makefile语法
问题一: $(CC) -c $^ -o $(ROOT_DIR)/$(OBJS_DIR)/$@ 这里的$^和$@是设么意思? 经过查找,该特殊符号的用法如下: 假如:all:library.cpp ma ...
- 鸟哥Linux私房菜基础学习篇学习笔记3
鸟哥Linux私房菜基础学习篇学习笔记3 第十二章 正则表达式与文件格式化处理: 正则表达式(Regular Expression) 是通过一些特殊字符的排列,用以查找.删除.替换一行或多行文字字符: ...
- GoLand2019 激活码
此教程对最新2019版本GoLand有效!!! 本教程对windows.mac.ubuntu全系统可用 此教程实时更新,请放心使用:如果有新版本出现猪哥都会第一时间尝试激活: goland官网下载地址 ...
- 【Caffe篇】--Caffe solver层从初始到应用
一.前述 solve主要是定义求解过程,超参数的 二.具体 #往往loss function是非凸的,没有解析解,我们需要通过优化方法来求解. #caffe提供了六种优化算法来求解最优参数,在solv ...
- 网络学习笔记(二):TCP可靠传输原理
TCP数据段作为IP数据报的数据部分来传输的,IP层提供尽最大努力服务,却不保证数据可靠传输.TCP想要提供可靠传输,需要采取一定的措施来让不可靠的传输信道提供可靠传输服务.比如:出现差错时,让发 ...