脚本第一行会指定由哪个程序来执行脚本中的内容,在linux bash编程中一般为:#!/bin/bash 或 #!/bin/sh
[root@mobanb ~]# bash --version
GNU bash, version4.1.2(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2009Free Software Foundation, Inc.
License GPLv3+:GNU GPL version 3 or later
This is freesoftware; you are free to change and redistribute it.
There is NOWARRANTY, to the extent permitted by law.
读取文件后开始执行脚本执行脚本的三种方式
1. bash script-name 或sh script-name推荐使用
脚本本身没有执行权限及文件x位为- 号或者开头没有指定解释器,推荐
2. path/script-name或 ./script-name当前路径下执行脚本
需要先将脚本文件的权限改为可执行chmod +x script-name 或chmod 755 script-name 推荐第一种代替
3. source script-name 或 . script-name #-->注意. 点号
脚本当中加载另一个脚本时使用,会把父shell的运行传到子shell中来
[root@mobanbscropts]# vi /etc/profile 在profile定义变量KLAUS
export KLAUS=1
[root@mobanbscropts]# . /etc/profile 重新启动profile文件
[root@mobanbscropts]# vi 1.sh 新建shell 1.sh
echo $KLAUS 使用变量KLAUS
[root@mobanbscropts]# sh 1.sh 执行1.sh会出现1
1
如果所有的shell都需要调用变量KLAUS,则需要在/etc/profile中定义变量KLAUS,
Shell脚本开发基本规范和习惯
1、#!/bin/bash 或 #!/bin/sh
可配置vim编辑文件时自动加上版本版权信息,方法是修改~./vimrc配置文件
2.脚本中尽量不要用中文注释
3.脚本已.sh为扩展名例:script-name.sh
4.代码书写优秀习惯:成对内容一次书写【[] {}“” ‘’ ``】 [ ]括号两端要有空格,流程控制语句一次书写完成,如if/for语
句格式一次写完,通过缩进让代码更易读 ;
变量基础及深入
环境变量(全局变量) 局部变量
1、位置变量:
$0 获取当前执行的shell脚本的文件名,如果执行脚本带路径那么就包括脚本路径;
$n 获取当前执行的shell脚本的第n个参数值,n=1..9,当n为0时表示脚本的文件名,如果n大于9时,大括号括起来$ {10}。
$* 获取当前shell的所有参数,将所有的命令行参数视为单个字符串,相当于"$1$2$3"...注意与$#的区别;
$# 获取当前shell脚本命令行中参数的总个数;
$@ 这个程序的所有参数"$1" "$2" "$3" "...",这是将参数传递给其他程序的最佳方式,因为他会保留所有内嵌在每个参数里的任何空白。
$0
[root@mobanbscropts]# cat n.sh
echo $0
[root@mobanbscropts]# sh n.sh
n.sh
[root@mobanbscropts]# sh /server/scropts/n.sh
/server/scropts/n.sh
[root@mobanbscropts]# sh `pwd`/n.sh
/server/scropts/n.sh
[root@mobanbscropts]# cat n.sh
dirname $0 路径
basename $0 文件名 printf 格式化打印
[root@mobanbscropts]# sh /server/scropts/n.sh
/server/scropts
n.sh
[root@mobanbscropts]# dirname /server/scropts/n.sh
/server/scropts
[root@mobanbscropts]# basename /server/scropts/n.sh
n.sh
[root@mobanbscropts]#vim /etc/init.d/crond
echo $"Usage: $0{start|stop|status|restart|condrest $0与下面的/etc/init.d/crond对应
art|try-restart|reload|force-reload}"
exit 2
esac
exit $?
[root@mobanbscropts]# /etc/init.d/crond
用法:/etc/init.d/crond {start|stop|status|restart|condrestart|try-restart|reload|force-reload}
[root@mobanbscropts]#
$n
[root@mobanbscropts]# cat p.sh
echo $1
[root@mobanbscropts]# sh p.sh oldboy
oldboy
[root@mobanbscropts]# sh p.sh oldboy oldgirl
oldboy
[root@mobanbscropts]# sh p.sh "oldboyoldgirl"
oldboy oldgirl
[root@mobanbscropts]# seq -s " " 15|sed's# # $#g' >q.sh
[root@mobanbscropts]# vi q.sh
1 $2 $3 $4 $5 $6$7 $8 $9 $10 $11 $12 $13 $14 $15
[root@mobanbscropts]# cat q.sh
echo $1 $2 $3 $4$5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15
[root@mobanbscropts]# sh q.sh {a..z}
a b c d e f g h ia0 a1 a2 a3 a4 a5
[root@mobanbscropts]# cat q.sh
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} ${14} ${15}
[root@mobanbscropts]# sh q.sh {a..z}
a b c d e f g h i j k l m n o
[root@mobanbscropts]#
$#获取当前执行的shell脚本后面接的参数的总个数
[root@mobanbscropts]# cat q.sh
echo $1 $2 $3 $4$5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} ${14} ${15}
echo $#
[root@mobanbscropts]# sh q.sh {a..z}
a b c d e f g h ij k l m n o
26
企业案例,控制用户传的参数个数
[root@mobanbscropts]# sh q1.sh zhangmiao
must two
[root@mobanbscropts]# cat q1.sh
[ $# -ne 2 ]&& {
echo "musttwo"
exit 1
}
echo klaus
[root@mobanbscropts]# sh q1.sh zhangmiao wangshuo
klaus
$*与$@
[root@mobanbscropts]# set -- "I am" handsome oldboy. 传入三个参数
[root@mobanbscropts]# echo $# 现有3个参数
3
[root@mobanbscropts]# for i in $*;do echo $i;done
循环打印这些参数,利用$* 不加引号把所有参数输出,然后第一个参数“I am”也拆开输出;
I
am
handsome
oldboy.
[root@mobanbscropts]# for i in "$*";do echo $i;done
循环打印这些参数,利用$* 加引号之后所有参数当做一个参数输出
I am handsomeoldboy.
[root@mobanbscropts]# for i in $@;do echo $i;done
循环打印这些参数,利用$@ 不加引号把所有参数输出,然后第一个参数“I am”也拆开输出;
I
am
handsome
oldboy.
[root@mobanbscropts]# for i in "$@";do echo $i;done
循环打印这些参数,利用$@ 加引号之后每个参数独立输出
I am
handsome
oldboy.
[root@mobanbscropts]# for i ;do echo $i;done 循环打印这些参数不加$@与$*
I am
handsome
oldboy.
2、进程状态变量
$$ 获取当前shell的进程号(PID)
$! 执行上一个指令的PID
$? 获取执行上一个命令的返回值(0为成功,非零为失败) 这个变量很常用
$_ 在此之前执行的命令或者脚本的最后一个参数
$?
[root@mobanbscropts]# su oldboy
[oldboy@mobanbscropts]$ echo $?
0
[oldboy@mobanbscropts]$ ll /root/
ls: 无法打开目录/root/: 权限不够
[oldboy@mobanbscropts]$ echo $?
2
[oldboy@mobanbscropts]$ dddd
bash: dddd:command not found
[oldboy@mobanbscropts]$ echo $?
127
[oldboy@mobanbscropts]$ sleep 1
^C
[oldboy@mobanbscropts]$ echo $?
130
[oldboy@mobanbscropts]$ ls -oldboy
ls:无效选项 -- y
请尝试执行"ls --help"来获取更多信息。
[oldboy@mobanbscropts]$ echo $?
2
0
|
表示运行成功 |
2 | 权限拒绝: -bash-4.1$ echo 1 >/root/a.log -bash:/root/a.log: permission denied -bash-4.1$ echo $? 1 |
1~125 | 表示运行失败,脚本命令、系统命令错误或参数传递错误; |
126 | 找到该命令了,但是无法执行; [root@salt-master scripts]#cat /etc/hosts -bash: /bin/cat:Permission denied [root@salt-master scripts]# echo $? 126 |
127 | 未找到要运行的命令; [root@C56 /]# oldboy;echo $? -bash: oldboy:command not found 127 |
>128 | 命令被系统强制结束 -bash-4.1$ sleep 200 ^C -bash-4.1$ echo $? 130 |
提示:在脚本调用,一般用exit 0,函数retrun 0。
[root@mobanbscropts]# cat q1.sh
[ $# -ne 2 ]&& {
echo "musttwo"
exit 1
}
echo oldgirl
[root@mobanbscropts]# sh q1.sh
must two
[root@mobanbscropts]# echo $?
1
[root@mobanbscropts]# cat q1.sh
[ $# -ne 2 ]&& {
echo "musttwo"
exit 111
}
echo oldgirl
root@mobanbscropts]# sh q1.sh
must two
[root@mobanbscropts]# echo $?
111 赋值给当前shell的$?变量了。
Shift
[root@mobanbscropts]# for i in "$@";do echo $i;done
I am
handsome
oldboy.
[root@mobanbscropts]# shift
[root@mobanbscropts]# help shift
shift: shift [n]
Shift positional parameters.
Rename the positional parameters $N+1,$N+2... to $1,$2 ... If N is
not given, it is assumed to be 1.
Exit Status:
Returns success unless N is negative orgreater than $#.
[root@mobanbscropts]#
$$
$$案例 当系统中某个脚本同时只能运行一个进程的时候使用
[root@mobanbscropts]# cat pid.sh
#!/bin/sh
pidpath=/tmp/a.pid
if [ -f"$pidpath" ]
then
kill -USR2 `cat $pidpath`
rm -f $pidpath
fi
echo $$>$pidpath
sleep 300
[root@mobanbscropts]# ps -ef|grep pid.sh |grep -v grep
[root@mobanbscropts]#
[root@mobanbscropts]# sh pid.sh &
[3] 1735
[root@mobanbscropts]# sh pid.sh &
[4] 1739
[root@mobanbscropts]# sh pid.sh &
[5] 1743
[root@mobanbscropts]# ps -ef|grep pid.sh |grep -v grep
root 1747 1455 0 14:18 pts/0 00:00:00 sh pid.sh
变量的处理计算变量长度与其他不同方法的耗时对比:
[root@mobanbscropts]# chars=`seq -s" " 100`
[root@mobanbscropts]# echo ${#chars}
291
[root@mobanbscropts]# echo $(expr length "$chars")
291
[root@mobanbscropts]# echo ${chars}|wc -L
291
[root@mobanbscropts]# time for i in $(seq 11111);do count=${#chars};done 最快
real 0m0.614s
user 0m0.614s
sys 0m0.000s
[root@mobanbscropts]# time for i in $(seq 11111);do count=`echo expr length"${chars}"`;done;
real 0m7.258s
user 0m0.903s
sys 0m1.615s
[root@mobanbscropts]# time for i in $(seq 11111);do count=`echo ${chars}|wc -L`;done; 最慢
real 0m23.339s
user 0m1.000s
sys 0m2.565s