shell简介
- Shell是一个命令行解释器,接收应用程序/用户命令,然后调用操作系统内核
- Shell还是一个功能强大的编程语言,易编写,调试,灵活性强
shell解析器
- linux提供的shell解析器有:
[root@CentOS ~]# cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/bin/dash
/bin/tcsh
/bin/csh
[root@CentOS ~]#
- bash和sh的关系
[root@CentOS ~]# cd /bin
[root@CentOS bin]# ll | grep bash
-rwxr-xr-x. 1 root root 941880 5月 11 2016 bash
lrwxrwxrwx. 1 root root 4 9月 27 22:21 sh -> bash
[root@CentOS bin]#
- CentOS默认的解析器是bash
[root@CentOS bin]# echo $SHELL
/bin/bash
Shell脚本
- 脚本格式:以
#!/bin/bash
开头(作用是指定解析器) - 创建一个shell脚本,输出hellworld
[root@CentOS bin]# touch helloworld.sh
[root@CentOS bin]# vim helloworld.sh
[root@CentOS bin]# sh helloworld.sh
[root@CentOS bin]# sh helloworld.sh
hello world
- 脚本常用的执行方式:第一种:采用bash或sh+脚本的相对路径或绝对路径(不用赋予脚本+x权限)
- sh+脚本的相对路径
[root@CentOS bin]# sh helloworld.sh hello world
- sh+脚本的绝对路径
[root@CentOS bin]# sh /home/root/bin/helloworld.sh hello world
- bash+脚本的相对路径
[root@CentOS bin]# bash helloworld.sh hello world
- bash+脚本的绝对路径
[root@CentOS bin]# bash /home/root/bin/helloworld.sh hello world
- 脚本常用的执行方式:第二种:采用输入脚本的绝对路径或相对路径执行脚本(必须具有可执行权限)
- 首先赋予要执行脚本的+x权限(可执行权限)
root@CentOS bin]# chmod 777 helloworld.sh
- 执行脚本:
- 相对路径:
root@CentOS bin]# ./helloworld.sh
- 绝对路径:
[root@CentOS bin]# ./home/root/bin/helloworld.sh
- 相对路径:
- 首先赋予要执行脚本的+x权限(可执行权限)
- 执行脚本的第一种方法:本质是bash解析器帮助执行脚本,所以脚本本身不需要执行权限
- 执行脚本的第二种执行方法:本质是脚本需要自己执行,所以需要执行权限
多命令的shell脚本
- 在/home/bin/目录下创建ryx.sh脚本,脚本执行后创建一个test.txt文件,并在test.txt文件中增加“测试文件”
touch ryx.sh
vi ryx.sh
// 在ryx.sh 脚本中输入以下内容
#!/bin/bash
touch test.txt
echo "测试文件" >> test.txt
Shell 变量
- 系统变量:
$HOME,$PWD,$SHELL,$USER
等 - 查看系统变量的值:
[root@CentOS bin]# echo $HOME
/root
- 显示当前shell中的所有变量
[root@CentOS bin]# set
BASH=/bin/bash
BASHOPTS=checkwinsize:cmdhist:expand_aliases:extquote:force_fignore:hostcomplete:interactive_comments:login_shell:progcomp:promptvars:sourcepath
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
BASH_CMDS=()
BASH_LINENO=()
BASH_SOURCE=()
BASH_VERSINFO=([0]="4" [1]="1" [2]="2" [3]="1" [4]="release" [5]="x86_64-redhat-linux-gnu")
BASH_VERSION='4.1.2(1)-release'
COLORS=/etc/DIR_COLORS
COLUMNS=97
CVS_RSH=ssh
DIRSTACK=()
shell自定义变量
基本语法
- 定义变量基本语法:变量=值
- 撤销变量基本语法:unset 变量
- 声明静态变量:readonly 变量 :注意:不能unset(会出大问题的)
变量定义规则
- 变量名称可以由字母,数字和下划线组成,但是不能以数字开头,环境变量名建议大写
- 等号两侧不能有空格
- 在bash中,变量默认类型都是字符串类型,无法直接进行数值运算
- 变量的值如果有空格,需要使用双引号或单引号括起来
基本案例
- 定义变量A :
[root@CentOS bin]# A=5
[root@CentOS bin]# echo $A
5
[root@CentOS bin]#
- 给变量A重新赋值
[root@CentOS bin]# A=8
[root@CentOS bin]# echo $A
8
[root@CentOS bin]#
- 撤销变量A
[root@CentOS bin]# unset A
[root@CentOS bin]# echo $A
[root@CentOS bin]#
- 声明静态变量B=2,不能unset
[root@CentOS bin]# readonly B=2
[root@CentOS bin]# echo $B
2
[root@CentOS bin]# B=9
-bash: B: readonly variable
[root@CentOS bin]#
- 在bash中,变量默认类型都是字符串类型,无法直接进行数值运算
[root@CentOS bin]# A=8+1
[root@CentOS bin]# echo $A
8+1
[root@CentOS bin]#
- 变量的值如果有空格,需要使用双引号或单括号括起来
[root@CentOS bin]# D=" 这是测试 (含空格)"
[root@CentOS bin]# echo $D
这是测试 (含空格)
[root@CentOS bin]#
- 可把变量提升为全局环境变量,可以供其他shell程序使用:
export 变量名
[root@CentOS bin]# vim helloworld.sh
在helloworld.sh文件中增加echo $B
#!/bin/bash
echo "helloworld"
echo $B
// 应该是输出 B 的值 9
[root@CentOS bin]# ./helloworld.sh
helloworld
发现并没有打印输出变量B的值,这是因为B不是全局变量
[root@CentOS bin]# export B
[root@CentOS bin]# ./helloworld.sh
helloworld
9
shell 特殊变量: $n
-
基本语法:
$n(描述 : n 为数字,$0代表脚本名称,$1-9代表第一个到第九个参数参数,十个以上的参数,需要用大括号包含如:${10}
-
案例:输出脚本文件名称,输入参数1和输入参数2的值
[root@CentOS bin]# touch par.sh [root@CentOS bin]# vim par.sh #!/bin/bash echo “$0 $1 $2” [root@CentOS bin]# chmod 777 par.sh [root@CentOS bin]# ./par.sh c1 c2 ./par.sh c1 c2
shell 特殊变量:$#
- 基本语法:$#(获取所有输入参数个数,常用于循环)
- 应用案例:
- 获取输入参数的个数
[root@CentOS bin]# touch par1.sh [root@CentOS bin]# vim par1.sh #!/bin/bash echo “$0 $1 $2” echo $# [root@CentOS bin]# chmod 777 par1.sh [root@CentOS bin]# ./par1.sh c1 c2 ./par.sh c1 c2 2
- 获取输入参数的个数
shell 特殊变量:$*和$@
$*
表示命令行中所有的参数,$*
把所有的参数看作了一个整体$@
:代表命令行中所有的参数,不过$@
把每个参数区分对待- 应用案例:打印输入的所有参数
[root@CentOS bin]# touch par1.sh [root@CentOS bin]# vim par1.sh #!/bin/bash echo “$0 $1 $2” echo $# echo $* echo $@ [root@CentOS bin]# chmod 777 par1.sh [root@CentOS bin]# ./par1.sh c1 c2 ./par.sh c1 c2 2 c1 c2 c1 c2
shell 特殊变量 $?
-
$?
表示最后一次执行命令的返回状态,如果这个变量的值为0,证明上一个命令正确执行,如果这个变量的值为非0(具体是正数还是负数,由命令自己决定),则证明上一个命令执行不正确 -
基本案例:判断 par.sh脚本是否正确执行
[root@CentOS bin]# touch par1.sh [root@CentOS bin]# vim par1.sh #!/bin/bash echo “$0 $1 $2” echo $# echo $* echo $@ [root@CentOS bin]# chmod 777 par1.sh [root@CentOS bin]# ./par1.sh c1 c2 ./par.sh c1 c2 2 c1 c2 c1 c2 [root@CentOS bin]# echo $? 0
shell 运算符
-
基本语法:
$((运算式))
或$[运算式]
-
expr
+ , - , \*, /, % 加,减,乘,除
,取余,expr运算符间要有空格 -
应用案例:
- 计算3+3
[root@centOS bin]# expr 2 + 3 5
- 计算3-2的值
[root@centOS bin]# expr 3-2 1
- 计算(2+3)* 4 的值
[root@centOS bin]# expr `expr 2+3` \ *4 20 ``` 4. 采用$[运算式]方式 ```c [root@centOS bin]# S=$[(2+3)*4] [root@centOS bin]# echo $S 20 ```
shell条件判断
-
基本语法:
[ condition ]
注意:condition前后要有空格 -
条件非空即为true,[ ryx ] 返回true ,[] 返回false
-
常用的判断条件
=
字符串之间比较- 两个整数之间比较
-lt
小于(less than)-le
小于等于(less equal)-eq
等于(equal)-gt
大于(greater than)-ge
大于等于(greater equal)-ne
不等于(Not equal)
- 按照文件权限进行判断
- -r 有读的权限
- -w 有写的权限
- -x 有执行的权限
- 按照文件类型进行判断
- -f 文件存在并且式一个常规文件(file)
- -e 文件存在(existence)
- -d 文件存在并且式一个目录(directory)
-
判断23是否大于等于22
[root@centOS bin]# [ 23 -ge 22 ] [root@centOS bin]# echo $? 0 ```
-
ryx.sh是否具有写的权限
[root@CentOS bin]# [ -w ryx.sh ] [root@CentOS bin]# echo $? 0 [root@CentOS bin]#
-
/home/bin/ryx/sh 目录是否存在
[root@CentOS bin]# [ -e /home/bin/ryx.sh ] [root@CentOS bin]# echo $? 1 [root@CentOS bin]#
-
多条件判断(&& 表示前一条命令执行成功时才执行后一条命令,|| 表示上一条命令执行失败后,才执行下一条命令)
[root@CentOS bin]# [ condition ] && echo OK || echo notok OK [root@CentOS bin]# [ condition ] && [ ] || echo notok notok
shell流程控制语句
shell流程控制——if语句
- if语句基本语法:
if [ 条件判断式 ];then
程序
fi
或者
if [ 条件判断式 ]
then
程序
fi
-
[ 条件判断式 ],中括号和条件判断式之间必须有空格
-
if 后要有空格
-
流程控制案例:
[root@CentOS home]# touch if.sh [root@CentOS home]# vim if.sh #!/bin/bash if [ $1 -eq "1" ] then echo "diyigecanshu,shi 1" elif [ $2 -eq "2" ] then echo "shi 2" fi ~ ~ "if.sh" 9L, 107C [root@CentOS home]# chmod 777 if.sh [root@CentOS home]# ./if.sh 1 diyigecanshu,shi 1
shell流程控制——case语句
-
基本语法:
case $变量名 in "值1") 如果变量的值等于值1,则执行程序1 ;; "值2") 如果变量的值等于值2,则执行程序2 ;; ...省略其他分支... *) 如果变量的值都不是以上的值,则执行此程序 ;; esac
-
case行尾必须为单词 in ,每一个模式匹配必须以右括号 )结束
-
双分号 ;; 表示命令序列结束,相当于break
-
最后一个 * 表示默认模式,相当于default
[root@CentOS home]# touch case.sh [root@CentOS home]# vim case.sh #!/bin/bash case $1 in "1") ehco "1" ;; "2") echo "2" ;; *) echo "bushi 1 he 2" ;; esac ~ [root@CentOS home]# chmod 777 case.sh [root@CentOS home]# ./case.sh 1 1 [root@CentOS home]#
shell流程控制——for循环
-
基本语法一
for((初始值;循环控制条件;变量变化)) do 程序 done
-
使用for从1加到100
[root@CentOS home]# touch f1.sh [root@CentOS home]# vim f1.sh #!/bin/bash s=0 for((i=0;i<=100;i++)) do s=$[$s+$i] done echo $s ~ ~ [root@CentOS home]# chmod 777 f1.sh [root@CentOS home]# ./f1.sh 5050 [root@CentOS home]#
-
语法二
for 变量 in 值1 值2 值3... do 程序 done
-
打印所有输入参数
[root@CentOS home]# touch f2.sh [root@CentOS home]# vim f2.sh #!/bin/bash for i in $* do echo "canshu $i " done [root@CentOS home]# chmod 777 f2.sh [root@CentOS home]# bash f2.sh c1 c2 c3 canshu c1 canshu c2 canshu c3 [root@CentOS home]#
$*和$@
的区别
$*和$@
都表示传递给参数或脚本的所有参数,不被双引号“”包含时,都以$1-$n
的形式输出所有参数
#!/bin/bash
for i in $*
do
echo "canshu $i "
done
for j in $@
do
echo "canshu $j "
done
~
[root@CentOS home]# bash f2.sh c1 c2 c3
canshu c1
canshu c2
canshu c3
canshu c1
canshu c2
canshu c3
[root@CentOS home]#
- 当
$*和$@被双引号“”包含时,“$*”会将所有参数作为一个整体,以“$1$2..$n”的形式输出所有参数,“$@”会将各个参数分开,以“$1”,"$2","$3",.."$n"的形式输出所有参数
#!/bin/bash
for i in "$*"
#$*中的所有参数看成是一个整体,所以这个for循环只会循环一次
do
echo "ban zhang love $i"
done
for j in "$@"
#$@中的每个参数都看成是独立的,所以“$@”中有几个参数,就会循环几次
do
echo "ban zhang love $j"
done
[root@CentOS home]# chmod 777 for.sh
[root@CentOS home]# bash f2.sh c1 c2 c3
canshu c1
canshu c1
canshu c2
canshu c3
shell-while循环
- 基本语法
while [ 条件判断式 ]
do
程序
done
- 案例
[root@CentOS home]# touch while.sh
[root@CentOS home]# vim while.sh
#!/bin/bash
s=0
i=1
while [ $i -le 100 ]
do
s=$[ $s+$i ]
i=$[$i+1]
done
ehco $s
[root@CentOS home]# chmod 777 while.sh
[root@CentOS home]# ./while.sh
5050