脚本执行方式
bash
+ 脚本sh
+ 脚本 | 1234567891011 | [root@mini01 ~]# mkdir shell[root@mini01 ~]# cd shell/[root@mini01 shell]# vi helloworld.sh#!/bin/bashecho helloworld[root@mini01 shell]# bash helloworld.shhelloworld[root@mini01 shell]# sh helloworld.shhelloworld[root@mini01 shell]# | | :—- | :—- |最好养成在脚本行首注明用哪个解释器解释执行的习惯!
赋予执行权限直接运行: | 123 | [root@mini01 shell]# chmod u+x helloworld.sh[root@mini01 shell]# ./helloworld.shhelloworld | | :—- | :—- |
在当前bash环境下运行: | 12345678910 | [root@mini01 shell]# vi helloworld.sh#!/bin/bashaaa=helloworld[root@mini01 shell]# ./helloworld.sh[root@mini01 shell]# echo $aaa[root@mini01 shell]# . ./helloworld.sh[root@mini01 shell]# echo $aaahelloworld | | :—- | :—- |
如果直接通过脚本路径执行脚本那么会让其在一个新的bash环境下执行,如果在前面再加上一个.
则会在当前bash环境下执行,bash环境不同的脚本之间无法共享变量。 | 12345678910111213141516171819 | [root@mini01 shell]# vi helloworld.sh#!/bin/bashaaa=helloworldsleep 20[root@mini01 shell]# . ./helloworld.sh &[1] 1483[root@mini01 shell]# pstreeinit─┬─auditd───{auditd} ├─crond ├─dbus-daemon───{dbus-daemon} ├─master─┬─pickup │ └─qmgr ├─6[mingetty] ├─rsyslogd───3[{rsyslogd}] ├─sshd─┬─sshd───bash─┬─bash───sleep │ │ └─pstree │ └─sshd───sftp-server └─udevd───2*[udevd] | | :—- | :—- |-
变量操作
set
,查看当前的环境变量有哪些unset 变量名
,撤销变量,但readonly
定义的变量无法撤销$变量名
,引用变量 | 1234 | [root@mini01 shell]# echo $PATH/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin[root@mini01 shell]# echo $PWD/root/shell | | :—- | :—- |变量名=变量值
,该变量仅在本次会话内有效(即在重启后或其他会话内无效),要想永久生效需在/etc/profile
中配置并使用source /etc/profile
刷新变量名="变量值"
,当变量值包含空格时需用双引号将其整体括起来,以将空格脱意(空格的本意是用来分割命令和参数、参数和参数) | 1234 | [root@mini01 shell]# aaa=hello world-bash: world: command not found[root@mini01 shell]# aaa=”hello world”[root@mini01 shell]# | | :—- | :—- |
但双引号仅使变量值中的空格脱意,其他特殊字符如变量引用符$
则仍然解析: | 1234 | [root@mini01 shell]# x=hello[root@mini01 shell]# y=”$x world”[root@mini01 shell]# echo $yhello world | | :—- | :—- |
这时要想y的变量值原样显示,则需使用单引号变量名='变量值'
,单引号会脱意变量值中的任何特殊字符 | 123 | [root@mini01 shell]# y=’$x world’[root@mini01 shell]# echo $y$x world | | :—- | :—- |export 变量名
,可以将变量提升为全局变量,可供其他shell使。source
就是将文件中的export
执行一遍。变量名=$(命令)
(或使用反引号)可以将命令的执行结果作为变量值复制给变量: | 123456789101112 | [root@mini01 shell]# wc -c helloworld.sh36 helloworld.sh[root@mini01 shell]# wc -c helloworld.sh | cut -d ‘ ‘ -f 1 #统计文件的字节数36[root@mini01 shell]# wordcount=wc -c helloworld.sh | cut -d ' ' -f1
[root@mini01 shell]# echo $wordcount36[root@mini01 shell]# wordcount=$(wc -c helloworld.sh | cut -d ‘ ‘ -f1)[root@mini01 shell]# echo $wordcount36 | | :—- | :—- |-
Shell中的特殊变量
$?
,上一条命令的退出状态(即程序返回值),如果程序没有返回值则表示程序退出的状态码,那么$?
为0表示成功执行,非0
则表示执行失败 | 1234567891011 | [root@mini01 shell]# ls -la 总用量 12 #这些只是命令执行过程中的输出而不是返回值drwxr-xr-x. 2 root root 4096 6月 7 19:41 .dr-xr-x—-. 6 root root 4096 6月 7 19:43 ..-rwxr—r—. 1 root root 36 6月 7 19:41 helloworld.sh[root@mini01 shell]# echo $?0[root@mini01 shell]# lss-bash: lss: command not found[root@mini01 shell]# echo $?127 | | :—- | :—- |
如果程序有返回值,那么$?
就是该值(如true
和false
就有返回值): | 123456 | [root@mini01 shell]# true[root@mini01 shell]# echo $?0[root@mini01 shell]# false[root@mini01 shell]# echo $?1 | | :—- | :—- |$$
,当前进程编号$0
,当前脚本名称$#
,参数个数$*
/$@
,参数列表 | 123456789101112131415161718192021 | [root@mini01 shell]# vi helloworld.sh#!/bin/bashfor p in $*do echo $pdonefor p in $@do echo $pdone[root@mini01 shell]# ./helloworld.sh p1 p2 p3 p4p1p2p3p4p1p2p3p4 | | :—- | :—- |
两者的区别是,加双引号时,“$*”
会作为一个整体,而“$@”
仍然以“$1” “$2” “$3”...
的形式存在: | 123456789101112131415161718 | [root@mini01 shell]# vi helloworld.sh#!/bin/bashfor p in “$*”do echo $pdonefor p in “$@”do echo $pdone[root@mini01 shell]# ./helloworld.sh p1 p2 p3 p4p1 p2 p3 p4p1p2p3p4 | | :—- | :—- |$n
,n位置的输入参数,n代表数字
运算符
格式:expr m + n
或$((m+n))
,注意:expr
以及+
的两边必须有一个空格
以(2+3)*4
的计算为例:
12345678 | [root@mini01 shell]# res=(2+3)4[root@mini01 shell]# echo $res(2+3)4[root@mini01 shell]# res=expr 2 + 3 [root@mini01 shell]# echo $res5[root@mini01 shell]# expr $res \* 420 |
---|---|
一步得出结果:
1234567 | [root@mini01 shell]# res=expr \\ expr 2 + 3\\\* 4 [root@mini01 shell]# echo $res20[root@mini01 shell]# res=$(((2+3)*4))[root@mini01 shell]# echo $res20 |
---|---|
流程控制
条件表达式
格式:[ <condition> ]
,注意[
的右侧和]
的左侧要有一个空格。
数字的比较:
lt less than, gt great than, le less than or equal to, ge great than or equal to, eq equal to, ne not equal to
字符串比较:=
可以使用$?
检测条件表达式的正确性,0为true,>0为false:
123456 | [root@mini01 shell]# [ 2 -gt 1 ][root@mini01 shell]# echo $?0[root@mini01 shell]# [ 2 -eq 3 ][root@mini01 shell]# echo $?1 |
---|---|
字符串的判断为true:
123 | [root@mini01 shell]# [ abc ][root@mini01 shell]# echo $?0 |
---|---|
可以借助&&
和||
实现如果condition1
成立则执行command1
否则执行command2
的效果:
12 | [root@mini01 shell]# [ 1 -gt 2 ] && echo yes || echo nono |
---|---|
文件相关的判断[ -r xx.sh]
:
- -r 有读的权限
- -w 有写的权限
- -x 有执行的权限
- -f 文件存在并且是一个常规的文件
- -s 文件存在且不为空
- -d 文件存在并是一个目录
- -b文件存在并且是一个块设备
-
for循环
for in
| 1234567891011121314151617181920 | [root@mini01 shell]# for N in 1 2 3> do> echo $N> done123[root@mini01 shell]# for N in 1 2 3;do echo $N;done123[root@mini01 shell]# for N in {1..3}> do> echo $N> done123 | | :—- | :—- |for ((i=n;i<m;i++))
| 12345678910111213141516 | [root@mini01 shell]# for ((i=1;i<=5;i++));do echo $i;done12345[root@mini01 shell]# for ((i=1;i<=5;i++))> do> echo $i> done12345 | | :—- | :—- |-
while循环
while [ <condition> ];do <command>;done
| 123456789 | [root@mini01 shell]# while [ 2 -gt 1 ]> do> echo “aa”> doneaaaaaaaa… | | :—- | :—- |
注意:[
、]
、-gt
的两边都必须要有一个空格。while ((<condition>));do <command>;done
| 12345678910 | [root@mini01 shell]# while ((i<=5))> do> echo $i> let i++> done12345 | | :—- | :—- |-
case语句
格式:
1234567891011 | case initem1) |
---|---|
例:
123456789101112131415 | [root@mini01 shell]# vi test-case.sh#!/bin/bashcase $1 instart) echo “starting…” ;;stop) echo “stopping..” ;;*) please enter “start” or “stop”esac[root@mini01 shell]# sh test-case.sh startstarting… |
---|---|
read命令
格式:read -p <提示信息> <变量名>
,提示并获取用户的输入(-p
指定提示信息),例:
123 | [root@mini01 shell]# sh test-read.shplease enter your password:123your input is 123 |
---|---|
if判断
格式:
123456789101112 | if [ |
---|---|
例:
1234567891011121314151617181920212223 | [root@mini01 shell]# vi test-if.sh#!/bin/bashread -p “please input your grade:” GRADEif [ $GRADE -ge 90 ] then echo Aelif [ $GRADE -ge 60 ] then echo Belse echo Cfi[root@mini01 shell]# sh test-if.sh 86please input your grade:86B[root@mini01 shell]# sh test-if.shplease input your grade:86B[root@mini01 shell]# sh test-if.shplease input your grade:54C[root@mini01 shell]# sh test-if.shplease input your grade:99A |
---|---|
自定义函数
格式:
12345 | function <函数名>() / function <函数名> / <函数名>(){ action… return |
---|---|
例:
123456789101112 | [root@mini01 shell]# vi sum.sh#!/bin/bashfunction sum(){ return expr $1 + $2 ;}sum 1 2;res=$?;echo $res;[root@mini01 shell]# sh sum.sh3 |
---|---|
注意: 1.必须在调用函数地方之前,先声明函数,shell脚本是逐行运行。不会像其它语言一样先预编译 2.函数返回值,只能通过
$?
系统变量获得,函数体末尾可以显式地加return
返回,如果不加,将以最后一条命令运行结果,作为返回值。return
后跟数值n(0-255)
脚本调试
sh -vx xx.sh
| 1234567891011121314151617181920212223242526 | [root@mini01 shell]# vi sum.sh#!/bin/bashfunction sum(){ returnexpr $1 + $2
;}sum 1 2;res=$?;echo $res;[root@mini01 shell]# sh -vx sum.sh#!/bin/bashfunction sum(){ returnexpr $1 + $2
;}sum 1 2;+ sum 1 2expr $1 + $2++ expr 1 + 2+ return 3res=$?;+ res=3echo $res;+ echo 33 | | :—- | :—- |
————————————————