Linux脚本

这周是最烧脑的一周,每天都沉迷在如何编写脚本中,我相信脚本这块让大家都很头疼,包括以后的工作肯定也离不开脚本。那么我们接下来针对脚本这块给大家做个详细的分析。

一、if语句

单分支:if 判断条件;then

条件为真的分支代码

fi

双分支:if 判断条件; then

条件为真的分支代码

else

条件为假的分支代码

fi

多分支:if 判断条件1; then

条件为真的分支代码

elif 判断条件2; then

条件为真的分支代码

elif 判断条件3; then

条件为真的分支代码

else

以上条件都为假的分支代码

fi

if语句的基本格式就是以上的形式,那么下面的两个例子让你对if语句加深印象

1、编写脚本/root/bin/filetype.sh,判断用户输入文件路径,显示其文件类型(普通,目录,链接,其它文件类型)

脚本思路(1)用read -p交互式让用户输入文件路径

(2)判断该文件是否存在,以防用户输入的文件是不存在的

(3)然后用-h,-d,-f分别判断文件是否为软连接,目录还是普通文件。

2、编写脚本/root/bin/checkint.sh,判断用户输入的参数是否为正整数

脚本思路(1)用read -p交互式提示用户输入数字

(2)判断用户是否输入的是正数

(3)判断用户输入的正数是否是小数,如何判断是否是小数,只用看是否带“.”就行

二、case语句

case 变量引用 in

pat1)

分支1

;;

pat2)

分支2

;;

*)

默认分支

;;

esac

case语句适用于判断输入的关键字,那么下来以例子的形式加深印象

1、判断用户输入的是yes或者是no。

脚本思路(1)read -p交互式提示用户输入字符串

(2)根据用户可能输入yes的各种形式去判断

(3)根据用户可能输入no的各种形式去判断

(4)除了yes或者no就给用户提示不知道输入的是什么意思

三、for语句

for 变量名 in 列表;do

循环体

done

列表的生成方式:

(1) 直接给出列表

(2) 整数列表:(a) {start..end}

(b) $(seq [start [step]] end)

(3) 返回列表的命令 $(COMMAND)

(4) 使用glob,如:*.sh

(5) 变量引用; [email protected], $*

for循环只要针对数字,下面还用事例加深for印象

1、编写脚本,提示输入正整数n的值,计算1+2+…+n的总和

脚本思路(1)read -p交互式提示用户输入正整数n

(2)判断用户输入的是否是正整数,如果不是正整数提示用户后并退出

(3)如果输入的是正整数,用for循环,列表是从1到n,循环体就是let sum+=$i

(4)直到循环n次后结束,输出sum值就行

2、打印九九乘法表

次数用到for嵌套for

脚本思路(1)九九乘法表需要循环九次

(2)外面每循环一次,里面就需要从1×到$sum

(3)里面循环结束都需要换行,所以要在内部循环结束后加echo

执行结果如下:

for语句的第二种用法:

for ((exp1;exp2;exp3)) ;do

command ;

done

用流程图表示如下:

四、while语句和untile语句

while语句:

while CONDITION ;do

循环体

done

untile语句:

until CONDIOION ;do

循环体

done

为什么要把while和untile语句放一块呢,因为这两个的用法刚好相反,while中当CONDITION为真的时候会一直循环下去,直到CONDITION为假就退出脚本。而untile中当CONDITION为假的时候会一直循环下去,直到CONDITION为真就退出脚本。

while的特殊用法:

while read line ;do

循环体

done < 文件路径

依次读取文件里面的每一行,且将行赋值给变量line

例如:截取出来UID大于100且小于200的值

下面我们用例子给大家展示一下while的用法以及untile的用法

1、编写脚本,求100以内所有正奇数之和

脚本思路(1)先定义i和sum的基础值

(2)然后用while循环,条件就为i小于100就退出

(3)循环体为let sum+=$i和i每次加2

2、禁止某个用户登录

脚本思路(1)用who命令去查看,然后把该用户截取出来

(2)每0.5秒检查一次,看该用户是否登录

(3)如果条件为真,那么就推出循环,就把该用户kill掉

while还能创建无限循环

while true ;do

循环体

done

此处的CONDITION只要换成true或者:就行

五、continue用法

continue只是结束本次循环进入下次循环,所以continue的位置一定要考虑清楚

例如:计算前100正奇数数的和,但是51不相加。

脚本思路(1)先定义i,sum的基础值

(2)循环判断i是否小于等于100

(3)判断i是否等于51,如果等于51就不去执行后面的命令,跳过本次循环

(4)如果不是51,判断余数是否等于1,等于1就去执行let sum+=I

(5)循环结束后,输出sum的值就行

六、break的用法

脚本中遇到break就直接结束循环体,相对于continue是直接退出循环体,而不是退出本次循环

对于上面例子,如果把continue换成break就是相当与遇到51后就直接退出循环体。

七、shift用法

shift适用于不确定的位置参数

例子:输入参数a b c d,依次创建四个账户。

脚本思路(1)先判断该用户是否输入参数,如果没有输入参数就直接退出,并提醒用户输入参数

(2)判断第一个参数是否存在,如果存在就创建用户shift将第一个变量删除,第二个变量成为第一个变量

(3)直到最后一个参数变为第一个参数结束时,退出循环。

八、select语法

select非常适用于编辑菜单脚本

例子:编写一个菜单

    

脚本思路(1)用select生成菜单编号和菜单名称

(2)用case语法检测用户输入的关键字

(3)这里的PS3是更改多行提示符

九、trap的用法

trap适用于脚本中信号捕捉,可以屏蔽一些信号。

trap ‘‘ 信号忽略信号的操作

trap ‘-‘ 信号恢复原信号的操作

trap -p 列出自定义信号操作

例子:

这个脚本只是针对trap的一些用法,大家可以去试试。

十、函数

函数function是由若干条shell命令组成的语句块,实现代码重用和模块化编程

它与shell程序形式上是相似的,不同的是它不是一个单独的进程,不能独立运行,而是shell程序的一部分

函数和shell程序比较相似,区别在于:

Shell程序在子Shell中运行

而Shell函数在当前Shell中运行。因此在当前Shell中,函数可以对shell中变量进行修改

定义一个函数:

function () {

...函数体...

}

删除一个函数:unset function

查看一个函数:declare -i function

脚本里面的返回值:return

return和exit的区别:return专应用于函数,相当于exit退出脚本,但是函数是当前Shell ,如果要用exit就直接退出了,所以需要用return。函数中尽量不写exit

生成环境函数:export -f function

我们的机器开机的时候在启动一些服务时候后面总是显示[ok]或者[FAILED]。这是通过调用/etc/init.d/functions/里面的函数实现的:

例子:

编写服务脚本/root/bin/testsrv.sh,完成如下要求

(1) 脚本可接受参数:start, stop, restart, status

(2) 如果参数非此四者之一,提示使用格式后报错退出

(3) 如是start:则创建/var/lock/subsys/SCRIPT_NAME, 并显示“启动成功”

考虑:如果事先已经启动过一次,该如何处理?

(4) 如是stop:则删除/var/lock/subsys/SCRIPT_NAME, 并显示“停止完成”

考虑:如果事先已然停止过了,该如何处理?

(5) 如是restart,则先stop, 再start

考虑:如果本来没有start,如何处理?

(6) 如是status, 则如果/var/lock/subsys/SCRIPT_NAME文件存在,则显示“SCRIPT_NAMEis running...”

如果/var/lock/subsys/SCRIPT_NAME文件不存在,则显示“SCRIPT_NAME is stopped...”

其中:SCRIPT_NAME为当前脚本名(testsrv.sh) -e 文件路径  判断该文件是否存在

执行结果如下:

有兴趣的可以看下是如何实现的

其中的代码如下:

f_start() {

ls /var/lock/subsys/testsrv.sh &> /dev/null

if [ $? -eq 0 ];then

action "该服务已经启动" true

else

touch /var/lock/subsys/testsrv.sh

action "启动成功" true

fi

}

f_stop() {

ls /var/lock/subsys/testsrv.sh &> /dev/null

if [ $? -eq 0 ];then

rm -f /var/lock/subsys/testsrv.sh

action "停止完成" false

else

action "该服务已经停止" false

fi

}

f_restart() {

f_stop &> /dev/null

f_start &> /dev/null

action "该服务已经重新启动" true

}

f_status() {

ls /var/lock/subsys/testsrv.sh &> /dev/null

if [ $? -eq 0 ] ;then

action "testsrv.sh is running..." true

else

action "testsrv.sh is stopped..." false

fi

}

echo $1 |egrep -o "\<start\>|\<stop\>|\<restart\>|\<status\>" &> /dev/null

[ $? -ne 0 ] && { echo "请准确输入!!"; exit 10; }

. /etc/init.d/functions

if [ "$1" == start ];then

f_start

elif [ "$1" == stop ];then

f_stop

elif [ "$1" == restart ];then

f_restart

else

f_status

fi

整体思路就是,定义四个函数f_start,f_stop,f_restart,f_status。然后在脚本里面掉调用这四个函数就行。

十一、数组

数组:(有稀疏格式,有连续格式)

创建数组时候先声明变量:(在脚本里面也是先声明数组)

declare -a 数组名称     声明普通数组

declare -A 数组名称     声明关联数组

关联数组与普通数组不能相互转换

创建数组:

一次只赋值一个的时候:数组名称[number]=名称 weekdays[0]=Sunday

直接添加变量到数组中是最后一个:数组名称[${#数组名称(*)}]=val4

一次性赋值全部元素的时候,如果有特殊符号的时候需要加””:数组名称=(“val1”“val2”“val3”....)

例如:title=([0]=wang [1]=xiaoming [2]=”xiaohong”)

只赋值特定元素的时候:数组名称=([0]=“val1” [2]=“val2”....)

例如:title=([0]=wang [2]=xiaoming [4]=”xiaohong”)

交互式数组赋值:read -a 数组名称

显示数组里面的变量:

显示单个数组里面的变量:echo ${数组名称[number]}

显示数组里面全部的变量:echo ${数组名称[*]}或者echo ${数组名称[@]}

显示数组里面全部变量的个数:echo ${#数组名称[*]}

删除数组里面的变量

删除数组中的单个变量:unset 数组名称[number]

删除数组中的最后一个变量:unset 数组名称[$[${#数组名称[*]}-1]]

删除整个数组:unset 数组名称

declare -a 查看数组

数组切片:

echo ${数组名称[*]:number1:number2}

number1:要跳过的元素个数

number2:要取出的元素个数

例子:编写脚本实现生成是个数字,比较出最大的和最小的数字

例子:编写一个脚本,把/var/log/*.log放入数组中,并计算出偶数下表的总行数

其实我们平时写脚本的时候,可以先在本上把思路写好,然后按照本上的思路先都敲出来,然后再慢慢排错,我感觉这样写脚本会比边想边敲代码效率会更高。大家可以去尝试一下!

但是每个人有每个人的学习方法,在此仅仅是建议。希望能够帮到大家!!

时间: 2024-10-10 20:18:19

Linux脚本的相关文章

Linux脚本——使用echo从一个文件写入另一个文件末尾

echo $(cat 你需要的文件) >> ./目的文件 使用cat获取你想要的文件内容,然后使用echo写入.问题在于cat获取的\n可能失效.如果单纯的作为ACM输入测试数据使用,还是有些价值的.--当然也可以直接生成:Python生成测试数据 $?用于返回上一个程序的执行结果: diff file file2用于判断两个文件是否相同--如果相同,返回0.可以用上一个命令查看. echo和cat的简单区别: 1. 想看一个文件的内容是什么,可以用cat,比如 cat /etc/reslov

Runtime.getRuntime.exec()执行linux脚本导致程序卡死有关问题

Runtime.getRuntime.exec()执行linux脚本导致程序卡死问题问题: 在Java程序中,通过Runtime.getRuntime().exec()执行一个Linux脚本导致程序被挂住,而在终端上直接执行这个脚本则没有任何问题.原因: 先来看Java代码: public final static void process1(String[] cmdarray) {        Process p = null;        BufferedReader br = null

Linux 脚本编写基础

1. Linux 脚本编写基础1.1 语法基本介绍1.1.1 开头程序必须以下面的行开始(必须放在文件的第一行):#!/bin/sh 符号#!用来告诉系统它后面的参数是用来执行该文件的程序.在这个例子中我们使用/bin/sh来执行程序. 当编辑好脚本时,如果要执行该脚本,还必须使其可执行. 要使脚本可执行:编译 chmod +x filename 这样才能用./filename 来运行1.1.2 注释 在进行shell编程时,以#开头的句子表示注释,直到这一行的结束.我们真诚地建议您在程序中使用

Linux脚本学习

练习写写Linux脚本,就是关于1+2+3+4累加的那个脚本,一直在报"syntax error near unpepected token  do",郁闷了半天,最后一点点找原因,原来把while写成了 为whlie了,去!

Linux 脚本 命令状态 条件测试

Linux 脚本: 脚本一般为文本文件,运行脚本事实上是运行一个bash进程,此进程负责从脚本文件中读取一个执行逻辑,而后由bash进程负责解析并运行此逻辑: 启动脚本: (1) # bash /PATH/TO/SCRIPT_FILE (2) 一个执行权限, # ./PATH/TO/SCRIPT_FILE [[email protected] ~]# vi date.sh  [[email protected] ~]# sh date.sh  #第一种执行方法 Thu, 17 Sep 2015 

执行linux脚本出现问题

1. 权限不够: 使用 chmod +x XXX.sh 提升权限 2. 出现:/bin/bash^M: bad interpreter: No such file or directory 原因:文件换行里出现\r\n  与linux格式不符合 安装dos2unix   apt-get install dos2unix 然后使用命令:#dos2unix myshell.sh  转换就行 执行linux脚本出现问题,布布扣,bubuko.com

linux 脚本测试网络速度

example: ./netspeed eth0 1 #!/bin/bash 2 3 INTERVAL="1"  # update interval in seconds 4 5 if [ -z "$1" ]; then 6 echo 7 echo usage: $0 [network-interface] 8 echo 9 echo e.g. $0 eth0 10 echo 11 exit 12 fi 13 14 IF=$1 15 16 while true 17

linux 脚本学习 一

linux 脚本学习 d:删除符合条件的行 sed '1,2d' /etc/fstab 删除1,2行,显示其他行 p:显示打印符合条件的行 sed '/^\//p'/etc/fstab 匹配的显示,加上原本的,会出现2个重复的 sed -n '/^\//p /etc/fstab 显示打印匹配的行 a:在指定的行后面添加/字符串 sed '/^\//a \#hello world'/etc/fstab \#hello world 经测试\# #都可以使用 i \string:在指定的行前面添加新行

linux脚本编程(shell)浅介 (转载)

linux脚本(shell)编程 啊,昨天上网看到一篇讲 linux/unix shell 的文章,想想自己最后写这东西也是一年前的事了,想想都快忘光了. 还是整理一下,做一次回顾,以后说不定还用得上:帖出来,方便第一次学习这东西的同道中人. 如果发现有错误的地方,请指出,留一句即可,我会感激的.废话少说了!!! linux 下最重要的脚本语言算是 bash 了,我也就写点这个吧(我也只会这个:)).跟其他开发语言(如C)比,bash 是比较简单的一种语言,主要用于写一些脚本代码,一些批处理或安

调用Runtime.getRuntime().exec()执行Linux脚本防挂死和返回脚本输出

1.在实际开发中,使用Runtime.getRuntime().exec()执行Linux脚本时,需要同时读取标准输出流与错误输出流缓冲区数据,因为操作系统缓冲区大小有限制,不及时处理会导致缓冲区占满而挂住,这种问题发生在于开发人员对该接口不了解而引发Bug. 具体可以通过使用两个线程同时去读错误和标准输出流缓冲区数据,然后用proc.waitFor()可以获取执行的结果.这种事最常见的场景,只关注脚本执行结果. 2.但在实际开发中,通过Runtime.getRuntime().exec()执行