Shell编程入门

1.初步了解:

Shell 就是贝壳的意思,内部是系统/内核, 外部则是用户。对于Shell 就是用于与内核之间的一个媒介。

shell 脚本的意义:

  • 如果实现同样的一个功能, 使用Shell脚本会比使用C语言简单快捷
  • 脚本中同样也是可以使用 变量、条件、计算、循环等等结构,相对与C语言来说比较简单
  • Shell 脚本中 上一个命令的输出可以作为下一个命令的输入

第一个Shell 脚本:

#!/bin/bash    # 告诉系统需要使用   /bin/bash 解析器来解析后面的所有命令

echo "Hello"   #  相当于C语言中的printf 输出一个字符串到屏幕(终端 )中

注意:

  • 第一行必须是 #!/bin/bash 为了告诉系统用使用bash 解析器来解析命令
  • 除了使用/bin/bash 以外还可以使用 awk / sed
  • Shell 脚本并不是什么复杂的程序, 在使用之前不需要提前编译程序
  • 文件后缀 C语言的后缀.c 而Shell 脚本的后缀是 .sh

2.变量

Shell 脚本是一种弱类型语言,在脚本当中使用变量不需要也无法指定变量的“类型”。缺省状态下,Shell 脚本的变量都是字符串,即一连串的单词列表。

定义与赋值:

myname="Michael Jackson"

注意:

  • 等号两边是不允许出现空格的
  • 双引号用来强调, 内部是一个完整的个体 (中间出现空格), 不然会被误会为一个命令

3.变量引用:

$ echo $myname

变量的种类

Shell 脚本中有这么几种变量:

A 普通的用户自定义变量,比如上面的 myname。

B 系统预定义好的环境变量,比如 PATH。

C 命令行变量,比如$#、$*等。

1,$# :代表命令行参数个数

2,$* :代表所有的参数

3,$@ :同上

4,$n :第 n 个参数

Shell 脚本中还有几个跟命令行变量形式很类似的特殊变量,他们是:

1,$? :代表最后一个命令执行之后的返回值

2,$$ :代表当前 Shell 的进程号 PID

4.特殊符号们:

引号:

双引号 “ ”

双引号的作用是将一些“单词”括起来形成单个的“值”。

在此变量的定义中如果没有双引号将会报错,因为这个字符串有两个单词,第二个单词会被认为是一个命令,但显然不对,因为 Jackson 不是命令而只是 myname 的一部分

单引号 ‘ ’

在单引号中所有的字符串都是字符串本意, 不能起到 引用、 命令的效果

反引号(抑音符) ` `

在双引号中可以直接解析一个命令

竖杠|(管道)

可以用来连接另个命令 , 把上一个命令的输出信息写入都管道文件中, 并把管道文件中的数据传递给下一个命令作为他的输入。

$ ls -l | wc   // ls -l的输出被转移都 wc当成他的输入

大于号> 和小于号

每一个进程在刚开始运行的时候,系统都会为他们默认地打开了三个文件,他们分别是

标准输入、标准输出、标准出错,其文件描述符和对应设备关系如下图所示

这三个标准文件对应两个硬件设备:标准输入是键盘,标准输出和标准出错是显示器(是

的,显示器设备被打开了两次,第一次打开为行缓冲类型的标准输出,第二次打开为不缓冲

类型的标准出错)。绝大多数的 Shell 命令,默认的输入输出都是这三个文件

把ls命令所输出的内容 从 1描述符 重定向输出到 a.txt 中

ls 1> a.txt
ls -l abc.c  > a.txt   // 假设abc.c文件不存在, 那么输出到 a.txt的内容为空
ls -l abc.c  2> a.txt  // 假设abc.c文件不存在, ls 则执行出错, 因此他的输出则是标准出错文件
                        // 所以 把原本需要输出都 2 号文件的内容 重定向为 a.txt

5.字符串处理:

1,计算一个字符串的字符个数:

:~$ str="Hello Gz2075"
:~$ echo "${#str}"

通配符:

* 代表任意长度的任意字符

? 代表一个长度的任意字符

[a-z] 代表一个长度 , 在a-z至之间的一个字符

[az] 代表一个长度,只能匹配 a 或者 z

[^az] 代表一个长度,不在 a 或 z 之内的字符(a和z以外的字符)

% 从右向左尽可能少的匹配字符

%% 从右向左尽可能多的匹配字符 (贪婪匹配)

# 从左向右尽可能少的匹配字符

## 从左向右尽可能多的匹配字符 (贪婪匹配)

"删除"(返回)字符串左边部分:

#!/bin/bash

str=HelloGz2075hellogz2069asdf2075ljklkj2075HelloEven

tet="${str#*2075}"   #从左往右尽可能少 匹配
abc="${str##*2075}" #从左往右尽可能多 匹配

echo $str  #HelloGz2075hellogz2069asdf2075ljklkj2075HelloEven
echo $abc   #HelloEven
echo $tet   #hellogz2069asdf2075ljklkj2075HelloEven

"删除"(返回)字符串右边部分:

#!/bin/bash

str=HelloGz2075hellogz2069asdf2075ljklkj2075HelloEven

tet="${str%2075*}"   #从右往左尽可能少 匹配
abc="${str%%2075*}"   #从右往左尽可能多 匹配

echo $tet  #HelloGz2075hellogz2069asdf2075ljklkj
echo $abc  #HelloGz

测试语句

专门用来实现所谓的测试语句,测试语句可以测试很多不同的情形

语句

含义

说明

test -e file

判断文件file是否存在

存在返回0,否则返回1

test -r file

判断文件file是否可读

可读返回0,否则返回1

test -w file

判断文件file是否可写

可写返回0,否则返回1

文件

test -x file

判断文件file是否可执行

可执行返回0,否则返回1

test -d file

判断文件file是否是目录

是目录返回0,否则返回1

test -f file

判断文件file是否是普通文件

是普通文件返回0,否则返回1

test -s file

判断文件file是否非空

非空返回0,否则返回1

test s1 = s2

判断字符串s1和s2是否相同

相同返回0,否则返回1

test s1 != s2

判断字符串s1和s2是否不同

不同返回0,否则返回1

test s1 < s2

判断字符串s1是否小于s2

s1小于s2返回0,否则返回1

字符串

test s1 > s2

判断字符串s1是否大于s2

s1大于s2返回0,否则返回1

test -n s

判断字符串s长度是否为非0

s长度为非0返回0,否则返回1

test -z s

判断字符串s长度是否为0

s长度为0返回0,否则返回1

test n1 -eq n2

判断数值n1是否等于n2

n1等于n2返回0,否则返回1

test n1 -ne n2

判断数值n1是否不等于n2

n1不等于n2返回0,否则返回1

test n1 -gt n2

判断数值n1是否大于n2

n1大于n2返回0,否则返回1

数值

test n1 -ge n2

判断数值n1是否大于等于n2

n1大于等于n2返回0,否则返回1

test n1 -lt n2

判断数值n1是否小于n2

n1小于n2返回0,否则返回1

test n1 -le n2

判断数值n1是否小于等于n2

n1小于等于n2返回0,否则返回1

eq

equal

等于

ne

not equal

不等于

gt

greater than

大于

ge

greater than equal

大于等于

lt

less than

小于

6.脚本语法单元

if 语句语法:
if    判断条件
then
    XXXXXXX
elif   判断条件
then 
    aaa
fi 

注意:

  • 每一个 if 语句都以 fi作为结束标记
  • if语句后面的条件必须为真时(0), then 后面的语句才会被执行
  • if 判断条件; 与 if 判断条件 效果是一致的 ,(分号有没有都可以)
#!/bin/bash

if test $# -ne 1   #判断 命令行输入的参数个数是否正确
then
    echo "参数错误~~"
fi

if test -e $1  # 判断文件是否存在
then 
    cat $1
else
    echo "文件不存在!!"
fi

case语句 (类似于C与语言的SWITCH CASE)

语法:

case 变量 in
    1)  11111 ;;
    2)  22222 ;;
    3)  33333 ;;
    *)  44444 ;;
esac 

例子, 用户输入数字脚本响应的输出 数据

#!/bin/bash

read num    # 从标准输入中读取一个数据 存放到  num 

case $num in
    1) echo "用户输入为 1 " ;;  # 注意   ;;  相当于C语言中的break
    2) echo "用户输入为 2 " ;;
    3) echo "用户输入为 3 " ;;
    4) echo "用户输入为 4 " ;;
    *) echo "用户输入为 其他 " ;;
esac   # 注意结束标记跟 if 一样 返过来写  case

注意:

  • num 是一个字符串,因此 1 ,2,3,4 都是字符串的形式
  • 整个 case 结构必须 esac 作为结束

7.循环控制:

使用while实现输出1 到100

#!/bin/bash

declare -i n=1 # 在定义变量 n 前面加上 declare -i 表示该变量为数值而不是字符串

while [ $n -le 100 ]   # -le判断 %n是否小于100 
do
    echo $n
    n=$n+1
done

使用until 实现输出1 到100 (直到某个条件满足才退出循环)

#!/bin/bash

declare -i n=1 # 在定义变量 n 前面加上 declare -i 表示该变量为数值而不是字符串
until [ $n -gt 100 ]   # -le判断 %n是否小于100 
do
    echo $n
    n=$n+1
done

for循环语句:

#!/bin/bash

files=`ls` # 在当前目录下执行 ls,将所有的文件名保存在变量 files 中
for a in $files # 循环地将 files 里面的每个单词赋给 a,赋完则退出循环
do
    if [ -f $a ] # 如果文件$a 是一个普通文件,那么就计算他的行数
    then
        wc -l $a  # 直接通过 wc 在终端打印输出  文件的行数和 文件名
    fi
done

8.函数

语法:

#!/bin/bash

func()     # 不需要填写形参  函数的定义中,括号里面不能写任何东西
{
    for a in $*
    do
        echo $a
    done
    return 99  # 默认返回值类型为 字符串类型
}

func  Hello  GZ2075 Even  # 调用 func 函数 并传递参数  Hello  GZ2075 Even 
echo "return value = $?"  # 打印输出 上一个命令的返回值  func 

trap 捕获信号

trap "" INT

上面语句的含义是:当脚本收到信号 SIGINT 时,忽略该信号

#!/bin/bash

do_something()
{
    echo "exit byebye!!"
}

echo $$    # 打印当前脚本文件的进程号 

trap do_something EXIT      # 设一个脚本正常退出的处理函数
trap do_something INT QUIT HUP # 设置捕获信号 INT QUIT HUP 并执行响应函数
                #  信的 前缀 SIG 必须忽略

sleep 5  # 随眠过程中并不会响应信号 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值