BASH 基本语法

it2026-02-04  2

本节内容

1.  什么是shell script

2.  变量

3.  运算符

4.  流程控制

5.  函数

6.  计划任务 crontab

 

一  什么是shell script

 

 

将OS命令堆积到可执行的文件里,由上至下的顺序执行文本里的OS命令,就是脚本

再加上些智能(条件/流控)控制,就变成了智能化脚本

read -p 'please input hostname: ' name hostnamectl set-hostname $name

 

二  变量

 

 

part1为何要有变量

程序的运行就是一些状态的变量 --> 用变量值的变化去表示

 

part2变量命名规则

以字母或下划线开头,剩下的部分可以是:字母、数字、下划线

最好遵循下述规范:

  1. 以字母开头

  2. 使用下划线做单词连接

  3. 同类型的用数字区分

  4. 对于文件最好加上扩展名  例如 sql_bak.tar.gz,  log_bak.tar.bz2

 

part3 系统变量

set:显示所有变量

env:环境变量

 

part4 变量赋值

VARNAME=VALUE

echo $VARNAME

删除变量 unset VARNAME

 

part5 常用系统变量

PATH  -->  第三方命令搜索路径PWD   -->  当前路径LANG  -->  字符编码 en_US.UTF-8

HOME        -->  家目录HISTSIZE    -->  历史命令条数PS1             -->  命令提示符 [root@myname ~]IFS              -->  域分隔符 是空格,换行,TAB键的合集

 

part6  全局变量与局部变量

当前用户进入bash后自己定义的变量,与系统变量(固化到文件里,启动时加载)不同

export var_name=var_value   #  export 声明全局变量

var_name=var_vale                # 声明局部变量

[root@localhost ~]# gender='male'               #  在爹这个位置定义一个局部变量gender[root@localhost  ~]# export money=1000   #  在爹这个位置定义一个全局变量money[root@localhost  ~]# bash                               #  切换到子bash[root@localhost  ~]# echo $gender              #  在儿子这里看它爹的局部变量gender,结果为空->看不到

[root@localhost  ~]# echo $money              #  在儿子这里看它爹的全局变量money,可以看到1000[root@localhost  ~]# export hobby='readding'  #  在儿子这里定义一个全局变量hobby[root@localhost  ~]# exit                                   # 退出,进入爹的bash环境exit[root@localhost  ~]# echo $hobby                    # 爹是看不到儿子的export的,儿子的儿子可以看到

[root@localhost  ~]#

 

part7  定义变量的边界

[root@myname ~]# moeny=10000[root@myname ~]# echo $moneyyuan

[root@myname ~]# echo ${money}yuan10000yuan[root@myname ~]#

 

part8  数据类型

bash中的变量无须声明,拿来就用,默认的变量都会时是字符类型,还可以有数字类型。普通脚本,这两种类型够用

 

实例:获取men_used

[root@myname ~]# free total used free shared buff/cache availableMem: 999936 529440 111152 9552 359344 239252Swap: 2097148 124208 1972940[root@myname ~]# mem_used=`free | awk 'NR==2{print $3}'`[root@myname ~]# echo $mem_used 529844

 

三 运算符

 

 

part1 算数运算符

  +

  -

  *

  /

  %

[root@www ~]# echo $[3+1]4

 

part2 关系操作

>  <  <=  >=  ==   !=  &&  ||  要与(())连用才能达到效果

test命令相关,[]可以达到相同效果

-gt  -lt  -le  -ge  -eq  -ne  -a  -o

[root@www ~]# x=1;y=2;a=10;b=5[root@www ~]# [ $x -lt $y -a $a -gt $b ][root@www ~]# echo $?0

 

part3  赋值运算符  

(( ))  里面不用写$,就可以取变量值

((x+=1))

((x-=1))

((x*=2))

((x/=2))

((x%=2))

[root@www ~]# x=1[root@www ~]# ((x=x+1))[root@www ~]# ((x=x+1))[root@www ~]# echo $x3

 

part4  shell里面的所有计算器

a=$[1+2]

a=$((x+=1))

expr 1 + 2

浮点运算,如内存使用率,bc    yum install -y bc

[root@www ~]# echo 'scale=2;3/10'|bc -l       # scale=2,保留2位小数.30[root@www ~]#

实例:求内存的百分比

[root@www ~]# free total used free shared buff/cache available Mem: 999936 456368 136924 9272 406644 329564 Swap: 2097148 150356 1946792 [root@www ~]# free | awk 'NR==2{print $2}' 999936 [root@www ~]# mem_total=`free | awk 'NR==2{print $2}'` [root@www ~]# mem_used=`free | awk 'NR==2{print $3}'` [root@www ~]# echo $mem_total 999936 [root@www ~]# echo $mem_used 456752 [root@www ~]# echo "scale=2;$mem_used/$mem_total" | bc -l .45 [root@www ~]# echo "scale=2;$mem_used/$mem_total" | bc -l | cut -d. -f2 45 [root@www ~]# mem_per=`echo "scale=2;$mem_used/$mem_total" | bc -l | cut -d. -f2` [root@www ~]# echo ${mem_per}% 45% [root@www ~]#

 

part5 测试操作

命令执行后会返回到一个系统变量中$?  如果$?值为0 表示命令执行成功,否则为失败

part5-1 测试文件状态

test -d  /etc  等价于 [ -d /etc  ]   然后用echo $? 查看结果状态    #  目录是否存在

-d  目录   [ -d /etc ]

-s  文件长度 > 0、非空

-e  文件 [ -d /etc/passwd ]

-f   普通文件[ -f /etc/passwd ]

-r  当前用户是否读权限  [ -r /etc/passwd ]

-w  当前用户是否写权限  [ -w /etc/passwd ]

-x  当前用户是否执行权限  [ -x /etc/passwd ] 

part5-2  测试字符串

=  两个字符串相等!= 两个字符串不相等-z  空串-n  非空串

part5-3  测试数值

-eq 等于

-ne 不等于

-gt 大于

-lt  小于

-ge 大于等于

-le 小于等于

-a 并列

-o 或者

 

四 流程控制

 

 

part1 分支流程

#!/bin/bash var='/etc/passwd' if [ -f $var ] then echo "$var is regular file" elif [ -b $var ] then echo "$var is block file" elif [ -d $var ] then echo "$var is directory" elif [ -h $var ] then echo "$var is link file" else echo "$var is unkown" fi

说明:

if...else 只有一个分支会执行

if 后面有then  else后面没有then

最后有个fi

 

以空格为单位 读取文本输入参数 $1 $2 $3 ... ${10}

[root@localhost temp]# cat b.sh #/bin/bash echo $1 echo $2 echo $3 echo ${10} echo ${11} [root@localhost temp]# ./b.sh 1 2 3 4 5 6 7 8 9 10 11 1 2 3 10 11

说明:

$$  进程pid

$*   所有参数

$@  所有参数

$#   参数个数

$?   上一条命令执行结果

 

简易启动nginx服务

#/bin/bash ps aux | grep nginx | grep -v 'grep' if [ $? -ne 0 ] then systemctl start nginx if

 

part2 循环结构

循环重复地做某件事

 

part2-1 while循环

while : do clear free sleep 1 done

1.   while死循环

#!/bin/bash var1=AAA var2=BBB var3=CCC while : do clear echo -e "A:${var1}\nB:${var2}\nC:${var3}" temp=$var1 var1=$var2 var2=$var3 var3=$temp sleep 1 done

2.  打印1 - 10

#!/bin/bash count=1while [ $count -le 10 ] do echo $count ((count++)) done

3.  登录 运行命令

#!/bin/bash while : do read -p "please input your username: " username read -p "please input your password: " password# 验证输入的有效性 if [ -z $username ] || [ -z $password ] then echo "usrename or password is none." continue fiif [ $username = 'alex' -a $password = '123456' ]# 用户名密码验证正确 then echo "Login successfully.Welcome $username" # 正确进行业务处理 while : do read -p "please input your cmd: " cmd if [ "$cmd" = 'quit' ] then break fi $cmd done else # 用户名密码验证错误 echo "Wrong username or password" fi done

 

part2-2 for循环

1. echo  1到100

#!/bin/bash for i in {1..100} # 1-100 do echo $i done

 

#!/bin/bash for i in `ls /boot` # ls /boot 命令结果 do echo $i done

 

#!/bin/bash for i in {2..253} do ping -c1 192.168.100.$i &> /dev/null if [ $? -ne 0 ] then echo "192.168.100.$i is available" fi done

 

part2-3 case语句

#!/bin/bash read -p ">>: " name case $name in root) echo "welcome root" ;; admin) echo "welcome admin" ;; default) echo "welcome default" ;; *) echo "no user $name" esac

 

part2-4 综合到一起,制作一个简单的菜单功能

#!/bin/bash echo "script name: `basename $0`" echo "version 1.0" echo "date 2017-10-09" echo "Author: Tom" while read -p "(h for help): " var do case $var in p|P|cpu|CPU) echo -e "\n\n" grep 'model name\|cpu MHz\|processor' /proc/cpuinfo |sort |uniq echo -e "\n\n" ;; m|m|mem|MEM) echo -e "\n\n" free echo -e "\n\n" ;; d|D|disk|DISK) echo -e "\n\n" df -Th echo -e "\n\n" ;; h|H|help|HELP) echo -e "\n\tcommand\taction\n\n" for i in cpu mem disk do echo -e "\t$i\t${i}_info" done echo -e "\thelp\tthis help page.." echo -e "\tquit\texit !!.." echo -e "\n\n" ;; q|Q|quit|exit) exit ;; *) echo -e "\n$var Enter Error...\n" esac done

 

 

五  函数

 

 

#!/bin/bash function start(){ echo "start..." } function install(){ echo "install..." } if [ "$1" = 'start' ] then start elif [ "$1" = 'install' ] then install else echo "cmd not found" fi

说明:

1.  交互命令行的函数 function abc(){echo 'aaa';echo 'bbb';}; abc ,另外脚本文件中也可以定义函数

2.  set 查看定义的函数;unset function_name 取消函数定义

3.  向函数传递参数就像脚本使用变量位置 $1, $2, $3, ... $9

4.  函数返回状态  echo $?,成功一般是返回0,定义自定义return 值

 

六  计划任务crontab

 

 

什么是计划任务

后台运行,到了预定时间就会自动执行的任务,前提是:事先手动将计划任务设定好,这就用到了crond服务

 

计划任务分为两类:系统级和用户级

无论是系统级还是用户级的cron计划都是文本文件。

系统的计划文件存放在 /etc/crontab路径下,用户的计划文件存放在/var/spool/cron/用户名

root用户可以直接对文件进行修改来编写计划任务也可以使用 crontab -e命令,而普通用户只能使用后者

[root@localhost ~]# crontab -e -u root         # 编辑 root 用户的计划任务

[root@localhost ~]# crontab -l -u root          # 查看 root 用户的计划任务

 

crontab任务配置基本格式:

*  *  *  *  *  command

分钟(0-59)  小时(0-23)  天(1-31)  月(1-12)  星期(0-7,0和7表示星期天)  命令

参 数: -e  编辑该用户的计时器设置

-l  列出该用户的计时器设置

-r  删除该用户的计时器设置

-u <用户名称>  指定要设定计时器的用户名称

注意:

1.   查看计划任务的执行:tail -f /var/log/cron

2.   写计划任务时,命令必须加上绝对路径,否则会出现这种情况:从日志中看,确实触发了计划任务的执行,但是命令却没有执行成功,

比如* * * * * reboot就会出现这种情况,需要将reboot写成/usr/sbin/reboot

 

crontab例子:

30 21 * * * /usr/local/etc/rc.d/apache restart # 每晚的21:30 重启apache 45 4 1,10,22 * * /usr/local/etc/rc.d/apache restart # 每月1、10、22日的4 : 45重启apache 10 1 * * 6,0 /usr/local/etc/rc.d/apache restart # 每周六、周日的1 : 10重启apache 0,30 18-23 * * * /usr/local/etc/rc.d/apache restart # 每天18 : 00至23 : 00之间每隔30分钟重启apache 0 23 * * 6 /usr/local/etc/rc.d/apache restart # 每星期六的11 : 00 pm重启apache * 23-7/1 * * * /usr/local/etc/rc.d/apache restart # 晚上11点到早上7点之间,每隔一个小时的每分钟重启 apache 0 */1 * * * /usr/local/etc/rc.d/apache restart # 每一小时重启apache 0 11 4 * mon-wed /usr/local/etc/rc.d/apache restart # 每月的4号与每周一到周三的11点重启apache 0 4 1 jan * /usr/local/etc/rc.d/apache restart # 一月一号的4点重启apache */30 * * * * /usr/sbin/ntpdate 210.72.145.44 # 每半小时同步一下时间 0 */2 * * * www /usr/bin/somecommand >> /dev/null 2>&1 # 以用户www的身份每两小时就运行某个程序: 0 1 * * * /home/testuser/test.sh # 每天1点调用/home/testuser/test.sh */10 * * * * /home/testuser/test.sh # 每10钟调用一次/home/testuser/test.sh 30 21 * * * /usr/local/etc/rc.d/lighttpd restart # 每天的21:30重启lighttpd 45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpd restart # 每月1、10、22日的4 : 45重启lighttpd 10 1 * * 6,0 /usr/local/etc/rc.d/lighttpd restart # 每周六、周日的1 : 10重启lighttpd 0,30 18-23 * * * /usr/local/etc/rc.d/lighttpd restart # 上面的例子表示在每天18 : 00至23 : 00之间每隔30分钟重启apache。 0 23 * * 6 /usr/local/etc/rc.d/lighttpd restart # 上面的例子表示每星期六的11 : 00 pm重启lighttpd * */2 * * * /usr/local/etc/rc.d/lighttpd restart # 每两小时的每分钟重启lighttpd 0 23-7/1 * * * /usr/local/etc/rc.d/lighttpd restart # 晚上11点到早上7点之间,每隔一小时重启lighttpd 0 11 4 * mon-wed /usr/local/etc/rc.d/lighttpd restart # 每月的4号与每周一到周三的11点重启lighttpd 0 4 1 jan * /usr/local/etc/rc.d/lighttpd restart # 一月一号的4点重启lighttpd */30 * * * * /usr/sbin/ntpdate 210.72.145.44 # 每半小时同步一下时间

 

更多信息

http://www.cnblogs.com/linhaifeng/p/6602149.html 

转载于:https://www.cnblogs.com/jonathan1314/p/7606907.html

相关资源:数据结构—成绩单生成器
最新回复(0)