1 Shell是什么

  Shell是一个命令行解释器,它为用户提供了一个向Linux内核发送请求以便运行程序的界面系统级程序,用户可以用Shell来启动、挂起、停止甚至是编写一些程序。

  Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。

  Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。我们使用ls、cd等命令都是交给了shell的。

 

2 shell脚本

  Shell 脚本(shell script),是一种为 shell 编写的脚本程序。

 

3 shell脚本入门

  1) 脚本以#!/bin/bash开头
  2) 脚本需要有可执行权限才能够执行
 

3.1 编写一个最基本的shell脚本

1)创建一个文件
  名字:myShell.sh
 
2)编辑内容,保存
#! /bin/bash         (必须以这个开头)
echo "hello world"    (打印hello world)

 

3)给这个脚本的创建用户赋执行的权限

 

4)执行脚本

  相对路径执行

  绝对路径执行

 

5)没有执行权限-执行脚本

  没有执行权限也可以执行该脚本,但是一般都会赋予可执行权限的,所以这种方式很少用到,也不推荐

 

4 Shell的变量

4.1 基本介绍

  1)Linux Shell中的变量分为,系统变量和用户自定义变量。
  2)系统变量:$HOME、$PWD、$SHELL、$USER等等
  3)显示当前shell中所有变量命令:set
 

4.2 变量的定义

  1) 变量名称可以由字母、数字和下划线组成,但是不能以数字开头。
  2) 等号两侧不能有空格
  3) 变量名称一般习惯为大写
 

4.3 普通变量<、h2>

4.3.1 简介

定义变量语法 变量名=值

参数的引用:$参数名

撤销变量语法 unset 变量名

 

4.3.2 实例

  定义变量a=100,打印到控制台

  撤销变量a,再次打印

 a=100 
 echo "a=$a"

 unset a
 echo "a=$a"

  

  执行结果

  

  第一个打印有值,撤销后再次打印,没有值了

 

4.4 静态变量(只读)<、h2>

4.4.1 简介

  加上关键字 readyonly

 

4.4.2 实例

  定义静态变量b=100打印,撤销,再次打印

  readonly b=100
  echo "b=$b"

  unset b
  echo "b=$b"

  

  执行结果

  

  两次都打印出来了

  中间报了错误信息,说明变量b只读,不能撤销

 

4.5 定义变量---命令结果赋值给变量

4.5.1 简介

  语法
  1)A=`ls -la` 运行里面的命令,并把结果返回给变量A
  2)A=$(ls -la)  运行里面的命令,并把结果返回给变量A

 

4.5.2 实例
  定义变量C,把ls -la的结果赋值给它,打印
  C=`ls -la`
  echo "$C"

  

  执行结果

  

 

4.6 定义环境变量

4.6.1 简介

  环境变量就是整个系统都可以使用,其它shell脚本也可以使用

  语法 export 变量名=变量值

 

4.6.2 实例

1)创建脚本myShell2.sh,创建环境变量 myvali=12345

  export myvali=12345

 

 

2)执行脚本

./myShell2.sh

 

3) 注意

  执行完成后,要使环境变量生效的话,还需要执行命令 source /etc/profile

  

 

4.6.3 验证环境变量

  执行命令 echo $myvali ,打印出结果表示成功

  

 

4.6.4 位置参数变量

  在shell脚本中填写变量,在命令行启动脚本的时候传入参数

 

1)基本语法

  $n (功能描述:n为数字,$0代表命令本身,$1-$9代表第一到第九个参数,十以上的参数,十以上的参数需要用大括号包含,如${10})
  $* (功能描述:这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体)
  $@(功能描述:这个变量也代表命令行中所有的参数,不过$@把每个参数区分对待)
  $#(功能描述:这个变量代表命令行中所有参数的个数)

 

2)示例
  #! /bin/bash
  echo "0号参数-命令=$0 第一个参数=$1 第二个参数=$2"
  echo "全部参数:$*"
  echo "全部参数$@"
  echo "参数的个数=$#

  

  执行命令:./param.sh 100 200

 

 可以看到,两个参数被接收到了 $*和$@是有区别的,具体在后面

 

4.7 预定义参数

4.7.1 简介

  shell设计者事先已经定义好的变量,也就是shell内置的变量,可以直接在shell脚本中使用
 
4.7.2 基本语法
  $$(功能描述:当前进程的进程号(PID))
  $!(功能描述:后台运行的最后一个进程的进程号(PID))
  $?(功能描述:最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行;如果这个变量的值为非0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确了)

 

4.7.3 示例

  #! /bin/bash
  echo "当前脚本进程=$$"
  #后台执行脚本./param.sh
  ./param.sh &
  echo "后台运行的最后一个进程=$!"
  echo "最后一次执行命令的返回状态=$?"

  

  执行
  

  可以看到打印了进程PID,并且执行了param脚本(没有传入参数,所以没有参数值)

 

5 运算符

5.1 基本语法

1) “$((运算式))”或“$[运算式]”
2) expr 运算式(m + n) 注意expr运算符间要有空格

 

5.2 示例

  脚本(用的是$[运算式]这种格式)
  #! /bin/bash
  echo "$[1+1]"
  echo "$[2*3]"
  echo "$[6/2]"
  echo "$[9%4]"
  echo "$[(5-3)*2*(-1)]"

  

  执行

  

 

6 流程if

6.1 语法

复制代码
  if [ 条件判断式 ] 
  then 
  程序
  elif [条件判断式]
  then
  程序
  fi
复制代码

  注意[ 条件判断式 ],中括号里面前后都有空格

 

6.2 常用条件判断

6.2.1 等于

复制代码
= 等于
-lt 小于
-le 小于等于
-eq 等于
-gt 大于
-ge 大于等于
-ne 不等于
复制代码

 

6.2.2 权限

-r 有读的权限
-w 有写的权限
-x 有执行的权限

 

6.2.3 文件
-f 文件存在并且是一个常规的文件
-e 文件存在
-d 文件存在并是一个目录

 

6.3 简单示例

6.3.1 判断大小-多个条件使用 &&
复制代码
#! /bin/bash

a=10
if [ $a -lt 10 ]
 then
  echo "个位数"
elif [ $a -ge 10 ] && [ $a -lt 100 ]
 then
  echo "十位数"
fi
复制代码

  执行

 

6.3.2 判断第一个参数大小

复制代码
#! /bin/bash


if [ $1 = 100 ]
 then
  echo $1
elif [ $1 = 200 ]
 then
  a=$[$1*2]
  echo $a
fi
复制代码

  执行

  

 

6.3.3 判断/usr/local是否存在

复制代码
#! /bin/bash


if [ -e /usr/local ]
 then
  echo "存在"
fi
复制代码

  执行

  

 

7 流程case

7.1 语法

复制代码
case $变量名 in 
"值1")
如果变量的值等于值1,则执行程序1 
;; 
"值2")
如果变量的值等于值2,则执行程序2 
;; 
…省略其他分支… 
*)
如果变量的值都不是以上的值,则执行此程序
;; 
esac
复制代码

  拿变量的值去和值1值2...一个个去对比

 

7.2 示例

复制代码
#! /bin/bash
case $1 in
 "100")
  echo "100"
;;
 "200")
  echo "200"
;;
 *)
 echo "其它"
esac
复制代码

  执行

 

8 流程for

8.1 语法1

for 变量 in 值1 值2 值3… 
do 
程序
done

 

8.2 示例

8.2.1 遍历100 200 300这三个数字

#! /bin/bash
for a in 100 200 300
 do
  echo $a
done

  执行

 

8.2.2 示例遍历传进来的所有参数

#! /bin/bash
for a in "$*"
 do
  echo $a
done

  这里只打印了一行数据,说明$*把三个参数当做一个参数了

 

8.2.3 遍历传进来的所有参数,和上面的区别是 $*没有引号

#! /bin/bash
for a in $*
 do
  echo $a
done

  执行

  这里只打印了三行数据,说明$*按三个参数在处理

 

8.2.4 示例

#! /bin/bash
for a in "$@"
 do
  echo $a
done

  执行

  这里只打印了三行数据,说明$@按三个参数在处理

  这就是$*和$@的区别了

 

8.3 语法2

for (( 初始值;循环控制条件;变量变化 )) 
do 
程序
done

 

8.4 示例

8.4.1 遍历1-10

#! /bin/bash
for((i=1;i<=10;i++))
 do
  echo $i
done

  执行

 

9 流程while

9.1 语法

while [ 条件判断式 ] 
do 
程序
done

 

9.2 示例

9.2.1 从1加到某个数的和,注意条件判断有空格,运算式没有空格

复制代码
#! /bin/bash
a=0
i=0
while [ $i -le $1 ]
 do
  a=$[$a+$i]
  i=$[$i+1]
done
echo $a
复制代码

  执行

 

10 控制台交互read

10.1 语法

语法:read(选项)(参数)
选项:
-p:指定读取值时的提示符;
-t:指定读取值时等待的时间(秒),如果没有在指定的时间内输入,就不再等待了。。
参数
变量:指定读取值的变量名

 

10.2 示例

10.2.1 不限制时间
  求两次输入的值的和
复制代码
#! /bin/bash

read -p "请输入一个正整数" num1

read -p "请输入一个正整数" num2

echo $[$num1+$num2]
复制代码

  当执行到read这一行时,会阻塞等待控制台输入值,两次输入的值会分别赋值给num1和num2

  执行

 

10.2.2 限制时间

  求两次输入的值的和

复制代码
#! /bin/bash

read -t 10 -p "请输入一个正整数" num1

read -t 10 -p "请输入一个正整数" num2

echo $[$num1+$num2]
复制代码

  当执行到read这一行时,会阻塞等待控制台输入值,但是值等待10秒,过了就往下执行,两次输入的值会分别赋值给num1和num2

  执行

 

11 函数

11.1 系统函数

  这里介绍两个常用的系统函数
 

11.2 basename

11.2.1 语法

语法:basename [pathname] [suffix]
pathname:路径
suffix:截取去掉尾巴的字符串
功能:返回完整路径最后 / 的部分,常用于获取文件名
 
11.2.2 示例-获取文件名

 

 11.2.3 示例-获取文件名且去掉后面的后缀

 

11.3 dirname

11.3.1 语法
语法:dirname 路径
返回完整路径最后 / 的前面的部分,常用于返回文件路径部分
 
11.3.2 示例

 

12 自定义函数

12.1 语法

function funname()
{
 Action;
 return int;
}
调用直接写函数名:funname 值1 值2 ....

 

12.2 示例-无返回值

  自定义函数名称为sum,有两个参数n1和n2,求得和

  通过read分别为n1和n2两个参数赋值,再调用函数sum

复制代码
function sum ()
 {
  echo $[$n1+$n2]
 }


read -p "请输入第一个参数" n1

read -p "请输入第二个参数" n2

sum $n1 $n2
复制代码

  执行

 

12.3 示例-有返回值

  自定义函数名称为sum,有两个参数n1和n2,求得和并返回

  通过read分别为n1和n2两个参数赋值,再调用函数sum,立即使用$?接收返回值,赋值给a

复制代码
#! /bin/bash
function sum ()
{
 return $[$n1+$n2]
}

read -p "请输入第一个参数" n1

read -p "请输入第二个参数" n2
sum $n1 $n2
a="$?"
echo $a
复制代码

  函数返回值在调用该函数后通过 $? 来获得