shell脚本的基础
shell 基本语法
变量
什么是shell?
先看一个简单的shell程序
[root@centos-6-1~]# cat linux.sh #查看linux.sh文件内容 #!/bin/bash
echo -e "e[1;31m linuxtouch e[0m"#红色字体输出 linuxtouch [root@centos-6-1 ~]# sh linux.sh linuxtouch [root@centos-6-1 ~]#
shell编程语言
编程语言:
1.低级语言
机器语言:二进制语言
汇编语言:符号语言,使用助记符来代替操作码,也就是用符号代替机器语言的二进制码;汇编程序把汇编语言翻译成机器语言的过程我们称为汇编
它们都是面向机器的语言
1.高级语言
它是比较接近自然语言或者说人类语言的一种编程,用人们能够容易理解的方式进行编写程序
静态语言:编译型语言 c c++ java
1.动态语言:解释型语言 php shellpython perl
编译器:(解释器)将人类理解的语言翻译成机器理解的语言
简单来说,最简单的SHELL就是一个由命令列表构成的可执行的文件。
命令解释器
BASE SHELL脚本的第一行以 #! 我们通常称它为sha-bang,这种表示法在技术上称为幻数模式。它表示文件是可执行的shell脚本。后面的路径名称是命令解释器,也就是应用于执行脚本的程序。
#!/bin/bash** **作用:告诉脚本使用的是哪种命令解释器。如不指shell,以当前shell作为执行的shell。
在shell中以#开始头表示整个行就被当作一个注释。执行时被忽略。
shell程序一般以.sh结尾,当然主要是看是否为执行,然后看里面有没有#!
不是只有*.sh的文件就可以执行,普通文件也可以
脚本的执行方式:
Shell脚本的执行通常有以下几种执行方式:
1.bash script-name或sh script-name (可以没有执行权限)
2.path/script-name 或./script-name(当前路径下执行脚本要有执行权限)
3.source script-name (可以没有执行权限)
4.sh < script-name 或 catscript-name | sh(同样适用于bash)
1.第一种执行方式:
[root@centos-6-1~]# bash linux.sh linuxtouch [root@centos-6-1 ~]# ll -h linux.sh -rw-r--r--. 1 root root 51 7月 20 14:42 linux.sh [root@centos-6-1 ~]#
2.第二种执行方式:
[root@centos-6-1~]# ./linux.sh -bash: ./linux.sh: 权限不够 [root@centos-6-1 ~]# chmod +x linux.sh [root@centos-6-1 ~]# ./linux.sh linuxtouch [root@centos-6-1 ~]# ll -h linux.sh -rwxr-xr-x. 1 root root 51 7月 20 14:42 linux.sh [root@centos-6-1 ~]#
3.第三种执行方式:
[root@centos-6-1~]# source linux.sh linuxtouch [root@centos-6-1 ~]# ll -h linux.sh -rw-r--r--. 1 root root 51 7月 20 14:42 linux.sh [root@centos-6-1 ~]#
4.第四种执行方式:
[root@centos-6-1~]# sh linux.sh linuxtouch You have new mail in /var/spool/mail/root [root@centos-6-1 ~]# ll -h linux.sh -rw-r--r--. 1 root root 51 7月 20 14:42 linux.sh [root@centos-6-1 ~]#
总结
1、脚本的执行顺序是从上到下,从左到右执行的
2、脚本里内容,可以理解为:好多单个命令集合,复杂一点脚本就是加上它自己的一些语法
创建shell程序的步骤:
第一步:创建一个包含命令和控制结构的shell文件。
第二步:修改这个文件的权限使它可以执行。使用chmod u+x
chmod u+x 就是此文件的主用户给予执行的权限
第三步:执行
shell变量及运用
变量是shell 传递数据的一种方法。变量是用来代表每个值的符号名。我们可以把变量当成一个容器,脚本可以在内存中存储数据,然后通过变量。就可以在脚本执行中进行修改和访问存储的数据
注意:
1、变量名称通常是大写字母,它可以由数字、字母(大小写)和下划线_组成。但是大家要注意变量名称不能以数字开头
2、等号 = 用于为变量分配值,在使用过程中等号两边不能有空格
3、变量存储的数据类型是整数值和字符串值
4、在对变量赋于字符串值时,建议大家用引号将其括起来。因为如果字符串中存在空格隔符号。BASH会把空格字符解释为单词分隔管符
5、要对变量进行调用,可以在变量名称前加美元符号$
BASESHELL的扩展功能:我们最常见的就是扩展变量值和命令替换和算术扩展
6、{name}的简化版本,但是在某些情况下,还必须使用花括号引起的方式来消除歧义并避免意外的结果
7、命令的替换就是将命令的调用替换为执行命令后的结果的输出,它的使用方式:我们将命令括在反引号中旧形式来调用命令结果,(新形式)是使用$()语法
8、在命令替换中,使用新语法$(),它允许进行嵌套命令替换
9、进行算术扩展时使用$[]进行,同时它也允许算术替换
Shell 有两类变量:局部变量和全局变量。
(1)局部变量:是shell 程序内部定义的,其使用范围仅限于定义它的程序,对其它程序不可见。
用户自定义的脚本中的变量,它会随着脚本的执行结束而结束
在用户的配置文件当中定义的环境变量,这个变量是会一直跟着用户存在,直到这个用户退出
(2)全局变量:是环境变量,其值不随shell 脚本的执行结束而消失。
$PATH
作用:运行某个命令的时候,本地查找不到某个命令或文件,会到这个声明的目录中去查找。
[root@centos-6-1~]# echo $PATH /usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin [root@centos-6-1 ~]#
(3)用户定义变量
由字母或下划线打头,不允许数字开头,后面由字母、数字或下划线组成,并且大小写字母意义不同。变量名长度没有限制。
使用变量值时,要在变量名前加上前缀“$”。
[root@centos-6-1~]# a=123 [root@centos-6-1 ~]# echo $a 123 [root@centos-6-1 ~]#
输出linuxtouch.blog.51cto.com必须用三个变量来输出
[root@centos-6-1~]# a=linuxtouch [root@centos-6-1 ~]# b=.blog. [root@centos-6-1 ~]# c=51cto.com You have new mail in /var/spool/mail/root [root@centos-6-1 ~]# echo $a$b$c linuxtouch.blog.51cto.com [root@centos-6-1 ~]#
主要赋值类型
(1)变量赋值:赋值号“=”两边应没有空格。
用“=”对变量赋值
[root@centos-6-1~]# A=123456 [root@centos-6-1 ~]# A = 123456 bash: A: command not found [root@centos-6-1 ~]#
(2)将一个命令的执行结果赋给变量
两种命令替换方式一种是反引号:`` 一种是$() ,其中反引号是不允许嵌套使用。后面的这个可以
[root@centos-6-1tmp]# file=`find /root/ -type f` [root@centos-6-1 tmp]# tar cvf a.tar $file tar: 从成员名中删除开头的“/” /root/.tcshrc /root/.bash_history /root/install.log.syslog /root/.bashrc /root/backup.sh /root/.cshrc /root/.viminfo /root/install.log /root/linux.sh /root/.bash_logout /root/aaa /root/.mysql_history /root/shuiguo /root/.Xauthority /root/qwer /root/anaconda-ks.cfg /root/abc /root/bbb /root/.bash_profile [root@centos-6-1 tmp]# ls a.taryum.logyum_save_tx-2017-07-05-16-47i3c1NX.yumtx crontab.cCtjgVyum_save_tx-2017-06-28-21-593muryN.yumtx [root@centos-6-1 tmp]#
[root@centos-6-1tmp]# OUTFILE=$(tar -cvf /tmp/a.tar $(find /root -type f)) tar: 从成员名中删除开头的“/” [root@centos-6-1 tmp]# echo $OUTFILE /root/.tcshrc /root/.bash_history/root/install.log.syslog /root/.bashrc /root/backup.sh /root/.cshrc/root/.viminfo /root/install.log /root/linux.sh /root/.bash_logout /root/aaa/root/.mysql_history /root/shuiguo /root/.Xauthority /root/qwer/root/anaconda-ks.cfg /root/abc /root/bbb /root/.bash_profile [root@centos-6-1 tmp]# ls /tmp/a.tar /tmp/a.tar You have new mail in /var/spool/mail/root [root@centos-6-1 tmp]#
可以利用变量和其它字符组成一个新的字符串
[root@centos-6-1~]# echo "$a"aaa /linux/touch/aaa [root@centos-6-1 ~]#
给变量赋值多个单词
[root@centos-6-1~]# [root@centos-6-1 ~]# name=linux [root@centos-6-1 ~]# echo $name linux [root@centos-6-1 ~]# name=touch [root@centos-6-1 ~]# echo $name touch [root@centos-6-1 ~]#
赋值时“ ” 和‘ ’的区别
[root@centos-6-1~]# echo "hehehe $name" hehehe touch You have new mail in /var/spool/mail/root [root@centos-6-1 ~]# echo 'hehehe $name' hehehe $name [root@centos-6-1 ~]#
总结:
单引号:之间的内容原封不动地指定给了变量。
双引号:特殊符号的含义保留。
变量与符号的综合演示
[root@centos-6-1~]# a=aaa [root@centos-6-1 ~]# echo "a=$a" a=aaa [root@centos-6-1 ~]# b='bbb' [root@centos-6-1 ~]# echo "b=$b" b=bbb [root@centos-6-1 ~]# echo 'b=$b' b=$b You have new mail in /var/spool/mail/root [root@centos-6-1 ~]# c="ccc" [root@centos-6-1 ~]# echo "c=${c}" c=ccc [root@centos-6-1 ~]#
把命令当做变量进行定义
[root@centos-6-1~]# linux=`date +%F` #利用反引号进行定义 [root@centos-6-1 ~]# echo $linux 2017-07-20 [root@centos-6-1 ~]# linux=$(date) #利用小括号进行定义,小括号可以进行嵌套 You have new mail in /var/spool/mail/root [root@centos-6-1 ~]# echo $linux 2017年 07月 20日星期四 16:22:07 CST [root@centos-6-1 ~]#
对变量的管理
set命令,例:
[root@centos-6-1~]# [root@centos-6-1 ~]# name=touch [root@centos-6-1 ~]# set | grep name name=touch [root@centos-6-1 ~]#
删除变量
[root@centos-6-1 ~]# unset name [root@centos-6-1 ~]# set | grep name _=name [root@centos-6-1 ~]# echo $name
You have new mail in /var/spool/mail/root [root@centos-6-1 ~]#
位置变量和特殊变量
Shell解释执行用户的命令时,将命令行的第一个字作为命令名,而其它字作为参数。由出现在命令行上的位置确定的参数称为位置参数。
使用$N 来表示
$0 获取当前执行shell脚本的文件文件名,包括脚本路径
$n 获取当前脚本的第n个参数n=0,1,2.....n 当n大于9时用{n}表示。
传递参数:
[root@centos-6-1~]# cat 8.sh #!/bin/bash # author:touch echo "----------------------" echo "Shell 传递参数实例!"; echo "执行的文件名:$0"; echo "第一个参数为:$1"; echo "第二个参数为:$2"; echo "第三个参数为:$3"; echo "----------------------"
[root@centos-6-1 ~]# sh 8.sh linux touch blog ---------------------- Shell 传递参数实例! 执行的文件名:8.sh 第一个参数为:linux 第二个参数为:touch 第三个参数为:blog ---------------------- [root@centos-6-1 ~]#
特殊变量
有些变量是一开始执行Script脚本时就会设定,且不能被修改,但我们不叫它只读的系统变量,而叫它特殊变量。这些变量当一执行程序时就有了,以下是一些特殊变量:
$* |
以一个单字符串显示所有向脚本传递的参数;如“$*” 用['']括起来的情况,以“¥1 ¥2 ...¥n”的形式输出所有参数 |
$# |
传递到脚本的参数个数 |
$@ |
与$*相同,但是使用时加引号,并在引号中返回每个参数 如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数 |
$$ |
这个程序的PID |
$? |
显示最后命令的退出状态;0表示没有错误,其他任何值表明有错误 |
$! |
上一个后台进程的ID |
[root@CentOS6-node1~]# cat a.sh echo $1 $2 $3 $4 $5 $6 $7 $8 $9 echo "脚本名字" echo $0 echo "脚本参数个数" echo "the number of values is $#" echo "脚本参数列表" echo $* echo "脚本参数列表" echo $@ echo "上一次执行结果的状态码" echo $? echo "这个程序的PID号" echo $$
[root@CentOS6-node1 ~]#
#执行结果
[root@CentOS6-node1 ~]# sh a.sh 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 脚本名字 a.sh 脚本参数个数 the number of values is 9 脚本参数列表 1 2 3 4 5 6 7 8 9 脚本参数列表 1 2 3 4 5 6 7 8 9 上一次执行结果的状态码 0 这个程序的PID号 3509 [root@CentOS6-node1 ~]#
注意:@ 区别
相同点:都是引用所有参数。
不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,,则 " * " 等价于 "1 2 3"(传递了一个参数),而 "@" 等价于 "1""2" "3"(传递了三个参数)
[root@CentOS6-node1~]# cat ab.sh echo $0 dirname $0 basename $0
[root@CentOS6-node1 ~]#
[root@CentOS6-node1 ~]# sh ab.sh ab.sh #执行的全路径 . #执行的目录 ab.sh #执行的文件名 [root@CentOS6-node1 ~]#
case"$1" in ##相当于执行/etc/init.d/vsftpd $1 start) start #当选择start时调用start函数来启动服务 ;;
stop) #当选择stop时调用stop函数来停止服务 stop ;; status) status-p ${pidfile} $httpd RETVAL=$? ;; restart) stop start ;; #当选择restart或者reload时先停止服务在启动服务 condrestart|try-restart) ifstatus -p ${pidfile} $httpd >&/dev/null; then stop start fi ;; force-reload|reload) reload ;; graceful|help|configtest|fullstatus) $apachectl $@ RETVAL=$? ;; *) echo$"Usage: $prog{start|stop|restart|condrestart|try-restart|force-reload|reload|status|fullstatus|graceful|help|configtest}" RETVAL=2 esac
当输出的$1不存在时,利用¥0来打印当前的执行脚本的方法
变量的数值计算
用于执行简单的整数运算
格式:$((算数运算符))
((表达式1,表达式2…))
特点:
1.在双括号结构中,所有表达式可以像c语言一样,如:a++,b--等。a++ 等价于 a=a+1
2.在双括号结构中,所有变量可以不加入:“$”符号前缀。
3.双括号可以进行逻辑运算,四则运算
4.双括号结构扩展了for,while,if条件测试运算
5.支持多个表达式运算,各个表达式之间用“,”分开
常用的算数运算符
运算符 |
意义 |
++ -- |
递增及递减,可前置也可以后置 |
+ - ! ~ |
一元运算的正负号逻辑与取反 |
+ - * / % |
加减乘除与余数 |
< <= > >= |
比较大小符号 |
== != |
相等不相等 |
>> << |
向左位移向右位移 |
& ^ | |
位的与位的异或位的或 |
&& || |
逻辑与逻辑或 |
? : |
条件判断 |
三种简单的赋值运算
[root@CentOS6-node1touch]# ((a=1+2**3-4%3)) [root@CentOS6-node1 touch]# echo $a 8 [root@CentOS6-node1 touch]#
[root@CentOS6-node1 touch]# b=$((a=1+2**3-4%3)) [root@CentOS6-node1 touch]# echo $b 8 [root@CentOS6-node1 touch]#
[root@CentOS6-node1 touch]# echo $((a=1+2**3-4%3)) 8 [root@CentOS6-node1 touch]# #省去一个定义变量
递增递减的应用
[root@CentOS6-node1touch]# echo $((a+=1)) #每次递增+1 9 [root@CentOS6-node1 touch]#
[root@CentOS6-node1 touch]# echo $((a++)) #每次递增+1 10 [root@CentOS6-node1 touch]#
[root@CentOS6-node1 touch]# echo $((a--)) #每次递减-1 8 [root@CentOS6-node1 touch]#
[root@CentOS6-node1 touch]# echo $a #a++或a--为先赋值再a加1或a减1 7
[root@CentOS6-node1 touch]# echo $((a++)) 6 [root@CentOS6-node1 touch]# echo $((a++)) 7 [root@CentOS6-node1 touch]# echo $a 8 [root@CentOS6-node1 touch]#
[root@CentOS6-node1 touch]# echo $((--a)) 6 [root@CentOS6-node1 touch]# echo $a 6 #--a或++a为先a加1或a减1 再进行a的赋值
比较大小
[root@CentOS6-node1touch]# echo $((1>2)) 0 [root@CentOS6-node1 touch]# echo $((1<=2)) 1 [root@CentOS6-node1 touch]#
#真为1 假为0
1到100所有整数和
[root@CentOS6-node1touch]# echo $((100*(1+100)/2)) 5050 [root@CentOS6-node1 touch]# echo $[100*$[1+100]/2] 5050 [root@CentOS6-node1 touch]#
写一个简单的四则运算的脚本
[root@CentOS6-node1touch]# cat !$ #此脚本的内容 cat 1.sh #!/bin/bash
a=6
b=2
echo "a-b=$(($a-$b))" echo "a+b=$(($a+$b))" echo "a*b=$(($a*$b))" echo "a/b=$(($a/$b))" echo "a**b=$(($a**$b))" echo "a%b=$(($a%$b))"
[root@CentOS6-node1 touch]#
[root@CentOS6-node1 touch]# sh !$ #脚本执行结果 sh 1.sh a-b=4 a+b=8 a*b=12 a/b=3 a**b=36 a%b=0 [root@CentOS6-node1 touch]#
#增强后的两种脚本 #第一种 [root@CentOS6-node1 touch]# sh 1-2.sh 1000 1000 a-b=0 a+b=2000 a*b=1000000 a/b=1 a**b=0 a%b=0 [root@CentOS6-node1 touch]# cat 1-2.sh #!/bin/bash
a=$1 b=$2 echo "a-b=$(($a-$b))" echo "a+b=$(($a+$b))" echo "a*b=$((a*b))" echo "a/b=$(($a/b))" echo "a**b=$[$a**$b]" echo "a%b=$[$a%$b]"
[root@CentOS6-node1 touch]#
#第二种 [root@CentOS6-node1 touch]# sh 1-3.sh enter a:345 enter b:678 a-b=-333 a+b=1023 a*b=233910 a/b=0 a**b=669693386503194833 a%b=345 [root@CentOS6-node1 touch]#
read命令
定义:
Read作用从键盘读入数据,赋给变量
[root@CentOS6-node1touch]# [root@CentOS6-node1 touch]# read a b c 11 22 33 [root@CentOS6-node1 touch]# echo $a 11 [root@CentOS6-node1 touch]# echo $b 22 [root@CentOS6-node1 touch]# echo $c 33 [root@CentOS6-node1 touch]#
在shell中使用read命令
[root@CentOS6-node1touch]# sh 2.sh input first second third : 11 22 33 the first parameter is 11 the second parameter is 22 the third parameter is 33 [root@CentOS6-node1 touch]# cat 2.sh #!/bin/bash echo "input first second third :" read firstsecond third echo "the first parameter is $first" echo "the second parameter is $second" echo "the third parameter is $third"
[root@CentOS6-node1 touch]#
参数用法
read answer 从标准输入读取一行并赋值给变量answer
read first last 从标准输入读取一行,直至遇到第一个空白符或换行符。把用户键入的第一个词存到变量first中,把该行的剩余部分保存到变量last中
read ?Cs passwd 将你输入的东西隐藏起来,值赋给passwd
read ?Ct 2 test 输入的时间限制
read ?Cn 2 test 输入的长度限制
read ?Cr line 允许输入包含反斜杠
[root@CentOS6-node1touch]# read -p "请输入你的准考证号: " ID 请输入你的准考证号:308611 [root@CentOS6-node1 touch]# echo $ID 308611 [root@CentOS6-node1 touch]#
[root@CentOS6-node1shell]# sh 3.sh 请输入你的姓名:张长浩 请输入你的年龄:17 请输入你的性别:男 你的基本信息如下: 姓名:张长浩 年龄:17 性别:男 [root@CentOS6-node1 shell]#
expr命令
作用:Shell变量的算术运算
对整数型变量进行算术运算,也可用于字符串
语法: expr 表达式 #注意运算符之间要有空格,特殊符号要转义
[root@CentOS6-node1shell]# expr $qwer1 * $qwer2 expr: 语法错误 [root@CentOS6-node1 shell]# expr $qwer1 * $qwer2 42435 [root@CentOS6-node1 shell]# expr $qwer1 / $qwer2 0 [root@CentOS6-node1 shell]#
字符串的处理
计算字符的长度
[root@CentOS6-node1shell]# expr length "ni hao a" 9 [root@CentOS6-node1 shell]#
抓取字符串中特定的字串,后面的数字表示从第3个字符开始,截取5个字符出来
[root@CentOS6-node1shell]# expr substr "this is aman" 3 5 is is [root@CentOS6-node1 shell]#
expr程序的例子
[root@CentOS6-node1touch]# sh 4.sh The value of value1 is 60 The value of value2 is 1 The value of value3 is 600 The value of value4 is 11 [root@CentOS6-node1 touch]# cat 4.sh #! /bin/sh a=10 b=20 c=30 value1=`expr $a+ $b + $c` echo "Thevalue of value1 is $value1" value2=`expr $c/ $b` echo "Thevalue of value2 is $value2" value3=`expr $c* $b` echo "Thevalue of value3 is $value3" value4=`expr $a+ $c / $b` echo "Thevalue of value4 is $value4"
[root@CentOS6-node1 touch]#
复杂的运算
[root@CentOS6-node1touch]# expr `expr 5 + 11` / $qwer42[root@CentOS6-node1 touch]# (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|