shell script

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
    1. 计算/etc/re.d/init/d/functions和/etc/initab文件的空白行之和;
      grep "^[[:space:]]*$" /etc/re.d/init/d/functions | wc -l

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 !

你可能感兴趣的:(shell script)