1.shell script基础
1.1.脚本文件格式:
[root@localhost scripts]# cat sh01.sh
#!/bin/bash
# Program:
# This program shows "Hello world!" in your screen.
# History:
# 2016/06/05 liuhui First release
echo -e "Hello World!"
exit 0
[root@localhost scripts]# bash sh01.sh
Hello World!
- 第一行,顶格:#!/bin/bash
- 代码注释:#
- 缩进,适度添加空白行;
- 脚本的状态返回值:
(1)默认是脚本中执行的最后一条命令的状态返回值;
(2)自定义退出状态码:exit[n](n为自己指定的状态码);
注意:shell进程遇到exit时,即会终止,因此,整个脚本执行即为结束;
1.2.变量:
- 局部变量
- 本地变量
- 环境变量
- 位置参数变量
- 特殊变量
1.2.1.位置参数变量
- myscript.sh argu1 argu2
引用方式:$1,$2,...,${10},${11},...
轮替:shift [n]:位置参数轮替;
1.2.2.特殊变量:
$0:脚本文件路径本身;
$#:脚本参数的个数;
$*:所有参数
$@:所有参数
- 1.练习:写一个脚本,通过命令行传递两个文本文件路径给脚本,计算其空白行数之和;
[root@localhost scripts]# cat sumspace.sh
#!/bin/bash
#
#
file1_lines=$(grep "^$" $1 | wc -l)
file2_lines=$(grep "^$" $1 | wc -l)
echo "The blank lines:$[$file1_lines+$file2_lines]"
[root@localhost scripts]# bash sumspace.sh sh01.sh sh02.sh
The blank lines:2
- 2.练习:写一个脚本,执行脚本后屏幕会显示如下的数据:
- 程序的文件名;
- 共有几个参数;
- 若参数的个数小于2则告知用户参数数量太少;
- 全部的参数内容;
- 第一个参数
- 第二个参数
[root@localhost scripts]# cat sh03.sh
#!/bin/bash
#Program:
# Program shows the script name,parameters...
echo "The script name is ==>$0"
echo "Total parameter number is ==> $#"
[ "$#" -lt 2 ] && echo "The number of parameter is less than 2. Stop here." && exit 0
echo "Your whole parameter is ==> '$@'"
echo "The 1st parameter ==> $1"
echo "The 2and parameter ==>$2"
[root@localhost scripts]# bash sh03.sh theone haha quot
The script name is ==>sh03.sh
Total parameter number is ==> 3
Your whole parameter is ==> 'theone haha quot'
The 1st parameter ==> theone
The 2and parameter ==>haha
- 3.练习:将脚本后面的变量进行偏移(shift);
[root@localhost scripts]# cat sh04.sh
#!/bin/bash
#Program:
# Program shows the effect of shift function.
echo "Total parameter number is ==> $#"
echo "Your whole parameter is ==> '$@'"
shift #进行第一次“一个变量的shift”
echo "Total parameter number is ==> $#"
echo "Your whole parameter is ==> '$@'"
shift 3 #进行第二次“三个变量的shift”echo "Total parameter number is ==> $#"
echo "Total parameter number is ==> $#"
echo "Your whole parameter is ==> '$@'"
[root@localhost scripts]# bash sh04.sh one two three four five six
Total parameter number is ==> 6
Your whole parameter is ==> 'one two three four five six'
Total parameter number is ==> 5
Your whole parameter is ==> 'two three four five six'
Total parameter number is ==> 2
Your whole parameter is ==> 'five six'
1.3.数据类型:字符型、数值型
- 弱类型:所有数据类型都处理为字符型
1.4.算术运算:
+,-,*,/,**,%
(1)let VAR=算数运算表达式:let sum=$num1+$num2
(2)VAR=$[算数运算表达式]:sum=$[$num1+$num2]
(3)VAR=$((算数运算表达式)):sum=$(($num1+$num2))
(4)VAR=$(expr$ARG1$OP$ARG2)
注意:乘法符号在有些场景中需要使用转义符;
1.5.增强型赋值:
- 变量做某种算术运算后回存至此变量中;
let i=$i+#
let i+=#
+=,-=,*=,/=,%=
- 自增:
VAR=$[$VAR+1]
let VAR+=1
let VAR++
- 自减:
VAR=$[$VAR-1]
let VAR-=1
let VAR--
练习:
- 1.计算/etc/passwd文件中的第10个用户和第20个用户的id号之和;
[root@localhost scripts]# cat sh02.sh
#!/bin/bash
# program:
# This program shows the sum of id about the tenth and the twentieth user in /etc/passwd
id1=$(head -10 /etc/passwd | tail -1 | cut -d: -f3)
id2=$(head -20 /etc/passwd | tail -1 | cut -d: -f3)
idsum=$(($id1+$id2))
echo $idsum
[root@localhost scripts]# bash sh02.sh
509
-
- 计算/etc/re.d/init/d/functions和/etc/initab文件的空白行之和;
grep "^[[:space:]]*$" /etc/re.d/init/d/functions | wc -l
- 计算/etc/re.d/init/d/functions和/etc/initab文件的空白行之和;
2.条件测试:
- (1)执行命令并利用命令状态返回值来判断;
0:成功
1-255:失败
- (2)测试表达式
test EXPRESSION
[EXPRESSION]
[[EXPRESSION]]
注意:EXPERSSION两端必须有空白字符,否则为语法错误;
- (3)bash的测试类型:
- 数值测试
- 字符串测试
- 文件测试
2.1. 数值测试:数值比较
-eq:是否等于;[$num1 -eq $num2]
-ne:是否不等于;
-gt:是否大于;
-ge:是否大于等于;
-lt:是否小于;
-le:是否小于等于;
2.2.字符串测试:
==:是否等于;
>:是否大于;
<:是否小于;
!=:是否不等于;
=~:左侧字符串是否能够被右侧的PATTERN所匹配;
-z"STRING":判断指定的字串是否为空;空则为真,不空则假;
-n"STRING":判断指定的字符串是否不空;不空则真,空则为假;
注意:
- (1)字符串要加引用;
- (2)要使用[[]];
2.3.文件测试:
2.3.1.存在性测试
-a FILE
-e FILE
文件的存在性测试,存在则为真,否则则为假;
2.3.2.存在性及类型测试
-b FILE:是否存在并且为块设备文件;
-c FILE:是否存在并且为字符设备文件;
-d FILE:是否存在并且为普通文件;
-h FILE或 -L FILE:是否存在并且为符号链接文件;
-p FILE:是否存在且为命名管道文件;
-s FILE:是否存在并且为套接字文件;
2.3.3.文件权限测试:
-r FILE:是否存在并对当前用户可读;
-w FILE:是否存在并且对当前用户可写;
-x FILE:是否存在并且对当前用户可执行;
2.3.4.特殊权限测试:
-u FILE:是否存在并且勇于suid权限;
-g FILE:是否存在并且勇于sgid权限;
-k FILE:是否存在并且拥有sticky权限;
2.3.5.文件是否有内容:
-s FILE:是否有内容;
2.3.6.时间戳:
-N FILE:文件自从上一次读操作后,是否被修改过;
2.3.7.从属关系测试:
-O FILE:当前用户是否为文件的属主;
-G FILE:当前用户是否属于文件的属组;
2.3.8.两个文件之间的比较:
FILE1 -e FILE2:FILE1与FILE2是否为指向同一个文件系统的相同iNode的硬链接;
FILE1 -nt FILE2:FILE1是否新于FILE2;
FILE1 -ot FILE2:FILE1是否旧与FILE2;
2.3.9.组合测试条件:
- 第一种方式:
COMMAND1&&COMMAND2
COMMAND1 || COMMAND2
!COMMAND
[-O FILE] && [-r FILE]
- 第二种方式:
EXPRESSION1 -a EXPRESSION2
EXPRESSION1 -o EXPRESSION2
!EXPRESSION1
[-O FILE -a -x FILE]
3.条件判断式
3.1.选择执行:
- 1.单分支的if语句:
if 测试条件;then
代码分支
fi
- 双分支的if语句:
if 测试条件;then
条件为真时执行的分支
else
条件为假时执行的分支
fi
3.2.示例:
- 通过参数传递一个用户给脚本,若用户不存在则添加之;
#!/bin/bash
#
if ! grep "^$1/>" /etc/passwd &> /dev/null; then
useradd $1
echo $1 | passwd --stdin $1 &> /dev/null
echo "Add user $1 finished."
fi
#!/bin/bash
#
if [$# -lt 1];then
echo"At least one username."
exit 2
fi
if ! grep "^$1/>" /etc/passwd &> /dev/null; then
useradd $1
echo $1 | passwd --stdin $1 &> /dev/null
echo "Add user $1 finished."
fi
#!/bin/bash
#
if [$# -lt 1];then
echo"At least one username."
exit 2
fi
if grep "^$1/>" /etc/passwd &> /dev/null; then
echo "user $1 exists."
else
useradd $1
echo $1 | passwd --stdin $1 &> /dev/null
echo "Add user $1 finished."
fi
练习
- 练习1:通过命令行参数给定两个数字,输出其中较大的数值;
#!/bin/bash
#
if [ $# -lt 2 ];then
echo "Two intergers"
exit 2
fi
if [ $1 -ge $2 ];then
echo "Max number:$1."
else
echo "Max number:$2."
fi
#!/bin/bash
#
declare -i max
if [ $# -lt 2 ];then
echo "Two intergers."
exit 2
fi
if [ $1 -ge $2 ];then
max=$1
else
max=$2
fi
echo "Max number:$max."
#!/bin/bash
#
if [ $# -lt 2 ];then
echo "Two intergers."
exit 2
fi
declare -i max=$1
if [ $1 -lt $2 ];then
max=$12
fi
echo "Max number:$max."
- 练习2:通过命令行参数给定用户一个用户名,判断其ID号是偶数还是奇数;
[root@localhost scripts]# cat sh05.sh
#!/bin/bash
#
if [ $# -lt 1 ];then
echo "Please input a argument."
exit 1
fi
idnum=$(id -u $1)
let mod=$idnum%2
if [ $mod -eq 0 ];then
echo "$1 is even"
else
echo "$1 is odd"
fi
[root@localhost scripts]# bash sh05.sh bash
bash is odd
[root@localhost scripts]# bash sh05.sh root
root is even
- 练习3:通过命令行参数给定两个文件名,如果某文件不存在,则结束脚本;都存在时返回每个文件的行数,并说明其中行数较多的文件;
[root@localhost scripts]# cat sh06.sh
#!/bin/bash
#
#!/bin/bash
if [ $# -lt 2 ];then
echo " Please input two arguments. "
exit 1
fi
if [ -e $1 -a -e $2 ];then
totalLines=$[ $(grep ".*" $1|wc -l)+$(grep ".*" $2|wc -l)]
echo " The total lines are $totalLines "
else
echo " the file doesn't exists !"
exit 1
fi
[root@localhost scripts]# bash sh06.sh sh01.sh sh02.sh
The total lines are 16
[root@localhost scripts]# bash sh06.sh sh01.sh
Please input two arguments.
[root@localhost scripts]# bash sh06.sh sh07.sh sh08.sh
the file doesn't exists !