Linux之编程:Linux Shell编程概述

简介

从程序员的角度来看, Shell本身是一种用C语言编写的程序,从用户的角度来看,Shell是用户与Linux操作系统沟通的桥梁(本质上来说,Shell每一行可以看做一个命令)。用户既可以输入命令执行,又可以利用 Shell脚本编程,完成更加复杂的操作。在Linux GUI日益完善的今天,在系统管理等领域,Shell编程仍然起着不可忽视的作用。深入地了解和熟练地掌握Shell编程,是每一个Linux用户的必修 功课之一。

LinuxShell种类众多,常见的有:Bourne Shell/usr/bin/sh/bin/sh)、Bourne Again Shell/bin/bash)、C Shell/usr/bin/csh)、K Shell/usr/bin/ksh)、Shell for Root/sbin/sh),等等。不同的Shell语言的语法有所不同,所以不能交换使用。每种Shell都有其特色之处,基本上,掌握其中任何一种 就足够了。在本文中,我们关注的重点是Bash,也就是Bourne Again Shell,由于易用和免费,Bash在日常工作中被广泛使用;同时,Bash也是大多数Linux系统默认的Shell。在一般情况下,人们并不区分 Bourne ShellBourne Again Shell,所以,在下面的文字中,我们可以看到#!/bin/sh,它同样也可以改为#!/bin/bash

Shell 基本格式

利用vi等文本编辑器编写Shell脚本的格式是固定的,如下:

 

#!/bin/sh

首行中的符号#!告诉系统其后路径所指定的程序即是解释此脚本文件的Shell程序。如果首行没有这句话,在执行脚本文件的时候,将会出现错误。

#comments

后续的部分就是主程序,Shell脚本像高级语言一样,也有变量赋值,也有控制语句。除第 一行外,以#开头的行就是注释行,直到此行的结束。如果一行未完成,可以在行尾加上",这个符号表明下一行与此行会合并为同一行。

Your commands go here

一个小的示例程序

#!/bin/sh
#example of shell
echo "first example"
echo #this inserts an empty line in output
echo "we are currently in the following directory"
/bin/pwd
echo
echo "this directory contains the following files"
/bin/ls


脚本执行

用户需要执行一个脚本,需要对这个脚本具有r权限,对脚本所在目录有rx权限。

l 创建一个包含命令和控制结构的文件。

l 修改这个文件的权限使它可以执行,使用chmod u+x

l 执行./example或者sh example

数据结构

变量定义

变量时shell传递数据的一种方法,用来代表每个取值的符号名。

Shell Script有两种类型的变量:

l 临时变量:Shell程序内部定义的,其使用范围仅限于定义它的程序,对其他程序不可见。包括了用户自定义变量、位置变量。

l 永久变量:永久变量是环境变量,其值不随shell脚本的执行结束而消失。

Shell Script是一种弱类型语言,其使用变量的时候不需要首先声明其类型。新的变量会在本地数据区分配内存进行存储,这个变量归当前的Shell所有,任何子进程都不能访问本地变量。

变量的辅助命令:

set

查看系统中所有定义的变量

unset 变量名

注意,不要加$符号

删除变量

 

用户自定义变量

变量赋值的方式是:

variable_name=variable_value 

【注意】赋值号两边应该没有空格,否则variable_name会被当做一个命令。

如果对一个已经有值的变量赋值,新值将取代旧值。取值的时候要在变量名前加$$variable_name可以在引号中使用,这一点和其他高级语言是明显不同的。如果出现混淆的情况,可以

v 用花括号来区分,例如:

echo "Hi, $as"

就不会输出“Hi, hello worlds”,而是输出“Hi。这是因为Shell$as当成一个变量,而$as未被赋值,其值为空。正确的方法是:

echo "Hi, ${a}s"

v 使用单引号,单引号中的变量不会进行变量替换操作。

譬如:$ABC = “time is $Date”,echo $ABC的值为:time is 2013-12-4

  $ABC = ‘time is $Date’,echo $ABC的值为:time is $Date 

 

永久变量

位置变量和特殊变量

Shell 解释执行用户命令时,将命令行的第一个部分(实际的命令加选项)作为命令名,其它部分作为参数。由出现在命令行上的位置确定的参数称为位置参数。例如:

ls -l file1 file2 file3

$0 这个程序的文件名 ls -l

$n 这个程序的第n个参数值,n=1-9

特殊变量

$*

这个程序的所有参数

$#

这个程序的参数个数

$$

这个程序的PID

$!

执行上一个后台命令的PID

$

执行上一个命令的返回值。

返回值为0表示上一个命令执行成功。

返回值不为0表示错误代码。

 

变量类型

基本类型

基本类型

定义时赋值,如NUM=1$NAME=’Zhang’或者$NAME=”张”。

命令类型

将一个命令的执行结果赋给变量,如:TIME=`date`,此时`称为命令替换符或者TIME=$(date)

变量

将一个变量赋值给另一个变量,如:A=$B

 

流程控制

变量测试Test

变量测试语句用于测试变量是否相等,是否为空,以及文件类型等等,基本格式为:

test 测试条件

文件测试

-b filename

filename 存在并且是块文件时返回真(返回0)

-c filename

filename 存在并且是字符文件时返回真

-d pathname

pathname 存在并且是一个目录时返回真

-e pathname

当由pathname 指定的文件或目录存在时返回真

-f filename

filename 存在并且是正规文件时返回真

-g pathname

当由pathname 指定的文件或目录存在并且设置了SGID 位时返回真

-h filename

filename 存在并且是符号链接文件时返回真 (或 -L filename)

-k pathname

当由pathname 指定的文件或目录存在并且设置了"粘滞"位时返回真

-p filename

filename 存在并且是命名管道时返回真

-r pathname

当由pathname 指定的文件或目录存在并且可读时返回真

-s filename

filename 存在并且文件大小大于时返回真

-S filename

filename 存在并且是socket 时返回真

-t fd

fd 是与终端设备相关联的文件描述符时返回真

-u pathname

当由pathname 指定的文件或目录存在并且设置了SUID 位时返回真

-w pathname

当由pathname 指定的文件或目录存在并且可写时返回真

-x pathname

当由pathname 指定的文件或目录存在并且可执行时返回真

-O pathname

当由pathname 存在并且被当前进程的有效用户id 的用户拥有时返回真(字母大写)

-G pathname

当由pathname 存在并且属于当前进程的有效用户id 的用户的用户组时返回真

file1 -nt file2

file1 file2 新时返回真

file1 -ot file2

file1 file2 旧时返回真

f1 -ef f2

files f1 and f2 are hard links to the same file

逻辑测试

-a

逻辑与,操作符两边均为真,结果为真,否则为假。

-o

逻辑或,操作符两边一边为真,结果为真,否则为假。

!

逻辑否,条件为假,结果为真。

举例: [ -w result.txt -a -w score.txt ] ;echo $? // 测试两个文件是否均可写

字符串测试

-z string

字符串string 为空串(长度为0)时返回真

-n string

字符串string 为非空串时返回真

str1 = str2

字符串str1 和字符串str2 相等时返回真

str1 == str2

同 =

str1 != str2

字符串str1 和字符串str2 不相等时返回真

str1 < str2

按字典顺序排序,字符串str1 在字符串str2 之前

str1 > str2

按字典顺序排序,字符串str1 在字符串str2 之后

举例: name="zqf"; [ $name = "zqf" ];echo $? // 打印 表示变量name 的值和字符串"zqf"相等

常见数值测试

常见数值测试

int1 -eq int2

如果int1 等于int2,则返回真

int1 -ne int2

如果int1 不等于int2,则返回真

int1 -lt int2

如果int1 小于int2,则返回真

int1 -le int2

如果int1 小于等于int2,则返回真

int1 -gt int2

如果int1 大于int2,则返回真

int1 -ge int2

如果int1 大于等于int2,则返回真

在 (()) 中的测试:

<

小于(在双括号里使用)

(("$a" < "$b"))

<=

小于等于 (在双括号里使用)

(("$a" <= "$b"))

>

大于 (在双括号里使用)

(("$a" > "$b"))

>=

大于等于(在双括号里使用)

(("$a" >= "$b"))

 

If 语句

变量测试语句一般不单独使用,一般作为if语句的测试条件,譬如:

if test -d $1 then

...

elif 条件2 then

...

fi

而变量测试语句可用[]进行简化,譬如:

test -d $1

等价于

[ -d $1 ]

Case

case 变量 in

字符串1) 命令列表1

;;

...

*) 通用命令

;;

esac

循环

While

while 条件

do

命令

done

Until

until 条件

do 

命令

done

until类似于while循环,不同的是until是条件返回值为假时才继续执行。

For

for 变量 in 名字列表

do

命令列表

done

#!/bin/sh

for DAY in Sunday Monday Tuesday

do

 echo "The day is : $DAY"

done

For语句也可以如下使用:

Vi hello.sh

#!/bin/bash

for((i=0;i<3;i++))

do

echo $i

done

流控制语句

v continue:继续当前循环

v break:跳出当前循环

Shell 命令

I/O输入输出

控制行

read

从键盘读入数据,赋值给变量

使用格式:

read UserName Para1 Para2,...

注意

l 输入参数个数小于定义,则缺省不赋值。

l 输入参数个数多于定义,则多余的参数会一次性赋给最后一个变量。

select

select 变量 in 关键字

do

command 1

...

command n

done

 

#!/bin/sh

echo "You choice?"

select var in "a" "b" "c";do

break;

done

echo $var

如果提示select not found,则

#!/bin/sh改为#!/bin/bash

执行脚本时将sh select.sh改为 bash select.sh

tee

读取标准输入的数据,并将其内容输出成文件。

语法:

tee [-ai][--help][--version][文件...]

参数:

-a--append :附加到既有文件的后面,而非覆盖它.

-i-i--ignore-interrupts :忽略中断信号。

--help :在线帮助。

--version :显示版本信息。

 

文件输入

 

运算

算术运算

expr

对整数型变量进行算术运算,注意运算参数之间的空格不可以省略。

expr 3 + 5

expr $var1 - 5

expr $var1 / $var2

expr $var3 \* 10  乘法需要转义字符

let

let 是 bash 內建的整數運算。arg 代表運算式。

當得到的值為 0,回應狀態值 1,其他數值,則回應狀態值 0

#!/bin/bash

let "t1 = ((a = 5 + 3, b = 7 - 1, c = 15 - 4))"

echo "t1 = $t1, a = $a, b = $b"

#!/bin/bash

let a=5+4 b=9-3

echo $a $b

进程控制

流程

exit

退出程序执行,并返回一个返回码,返回码为0表示正常退出,非0表示非正常退出

exit 0

 

字符串

统计

wc 命令

Linux系统中的wc(Word Count)命令的功能为统计指定文件中的字节数、字数、行数,并将统计结果显示输出。

1.命令格式:

wc [选项]文件...

2.命令功能:

统计指定文件中的字节数、字数、行数,并将统计结果显示输出。该命令统计指定文件中的字节数、字数、行数。如果没有给出文件名,则从标准输入读取。wc同时也给出所指定文件的总统计数。

3.命令参数:

-c 统计字节数。

-l 统计行数。

-m 统计字符数。这个标志不能与 -c 标志一起使用。

-w 统计字数。一个字被定义为由空白、跳格或换行字符分隔的字符串。

-L 打印最长行的长度。

-help 显示帮助信息

--version 显示版本信息

实例1:查看文件的字节数、字数、行数

命令:

wc test.txt

 

分隔

awk -F 

域分隔符‘命令’

示例:

1、检测系统中UID0的用户

awk -F: ‘$3==0 {print $1}’ /etc/passwd

2、检测系统中密码为空的用户

awk -F: ‘length($2)==0 {print $1}’ /etc/shadow

 

调试

sh -x script:使用+号表示脚本执行情况。

sh -n script:不执行脚本只是进行脚本的语法检测,返回所有的错误。

************DEMO************

文件管理

删除

自动清除过时文件

1创建shell

touch /opt/soft/bin/auto-del-30-days-ago-log.sh

chmod +x auto-del-30-days-ago-log.sh

新建一个可执行文件auto-del-30-days-ago-log.sh,并分配可运行权限

2编辑shell脚本:

vi auto-del-30-days-ago-log.sh

编辑auto-del-30-days-ago-log.sh文件如下:

#!/bin/sh

find /opt/soft/log/ -mtime +30 -name "*.log" -exec rm -rf {} \;

3计划任务:

#crontab -e

auto-del-30-days-ago-log.sh执行脚本加入到系统计划任务,到点自动执行

输入:

10 0 * * * /opt/soft/log/auto-del-7-days-ago-log.sh >/dev/null 2>&1

这里的设置是每天凌晨010分执行auto-del-7-days-ago-log.sh文件进行数据清理任务了。

搜索

监控指定大小的文件

查找当前目录中所有大于500M的文件,把这些文件名写到一个文本文件中,并统计其个数。

find ./ -size +500-type f | tee file_list | wc -l

在目录/tmp下找到100个以abc开头的文件,然后把这些文件的第一行保存到文件new中。

for filename in `find /tmp -type f -name "abc*"|head -n 100`

do

sed -n '1p' $filename>>new

done

每隔10分钟监控一次,监控/usr下如果大于5G,发邮件给管理员

#!/bin/bash

while true

do

    sleep 600

    n=$(du -s /usr | cut -f1)

    if [ $n -gt 5242880 ]

    then

        mail -s "greater" filwsyl@gmail.com < ~/filename #将文件filename的内容发送出去。

    fi

done

 

监控指定路径的文件

本书共分五部分,详细介绍了shell编程技巧,各种UNIX命令及语法,还涉及了UNIX下的文字处理以及少量的系统管理问题。本书内容全面、文字简洁流畅,适合Shell编程人员学习、参考。 目 录 译者序 前言 第一部分 shell 第1章 文件安全与权限 1 1.1 文件 1 1.2 文件类型 2 1.3 权限 2 1.4 改变权限位 4 1.4.1 符号模式 4 1.4.2 chmod命令举例 5 1.4.3 绝对模式 5 1.4.4 chmod命令的其他例子 6 1.4.5 可以选择使用符号模式或绝对模式 7 1.5 目录 7 1.6 suid/guid 7 1.6.1 为什么要使用suid/guid 8 1.6.2 设置suid/guid的例子 8 1.7 chown和chgrp 9 1.7.1 chown举例 9 1.7.2 chgrp举例 9 1.7.3 找出你所属于的用户组 9 1.7.4 找出其他用户所属于的组 10 1.8 umask 10 1.8.1 如何计算umask值 10 1.8.2 常用的umask值 11 1.9 符号链接 12 1.9.1 使用软链接来保存文件的多个映像 12 1.9.2 符号链接举例 12 1.10 小结 13 第2章 使用find和xargs 14 2.1 find命令选项 14 2.1.1 使用name选项 15 2.1.2 使用perm选项 16 2.1.3 忽略某个目录 16 2.1.4 使用user和nouser选项 16 2.1.5 使用group和nogroup选项 16 2.1.6 按照更改时间查找文件 17 2.1.7 查找比某个文件新或旧的文件 17 2.1.8 使用type选项 17 2.1.9 使用size选项 18 2.1.10 使用depth选项 18 2.1.11 使用mount选项 18 2.1.12 使用cpio选项 18 2.1.13 使用exec或ok来执行shell命令 19 2.1.14 find命令的例子 20 2.2 xargs 20 2.3 小结 21 第3章 后台执行命令 22 3.1 cron和crontab 22 3.1.1 crontab的域 22 3.1.2 crontab条目举例 23 3.1.3 crontab命令选项 23 3.1.4 创建一个新的crontab文件 24 3.1.5 列出crontab文件 24 3.1.6 编辑crontab文件 24 3.1.7 删除crontab文件 25 3.1.8 恢复丢失的crontab文件 25 3.2 at命令 25 3.2.1 使用at命令提交命令或脚本 26 3.2.2 列出所提交的作业 27 3.2.3 清除一个作业 27 3.3 &命令 27 3.3.1 向后台提交命令 28 3.3.2 用ps命令查看进程 28 3.3.3 杀死后台进程 28 3.4 nohup命令 29 3.4.1 使用nohup命令提交作业 29 3.4.2 一次提交几个作业 29 3.5 小结 30 第4章 文件名置换 31 4.1 使用* 31 4.2 使用? 32 4.3 使用[...]和[!...] 32 4.4 小结 33 第5章 shell输入与输出 34 5.1 echo 34 5.2 read 35 5.3 cat 37 5.4 管道 38 5.5 tee 39 5.6 标准输入、输出和错误 40 5.6.1 标准输入 40 5.6.2 标准输出 40 5.6.3 标准错误 40 5.7 文件重定向 40 5.7.1 重定向标准输出 41 5.7.2 重定向标准输入 42 5.7.3 重定向标准错误 42 5.8 结合使用标准输出和标准错误 43 5.9 合并标准输出和标准错误 43 5.10 exec 44 5.11 使用文件描述符 44 5.12 小结 45 ... ...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值