Shell脚本编程

简介

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

Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。

技术小贴
技术小贴

业界所说的 shell 通常都是指 shell 脚本,Shell 脚本(shell script),是一种为 shell 编写的脚本程序。

shell种类很多,包括sh、bash、xsh、ksh,其中bash是大多数Linux系统默认的shell,下面也将以bash为例。

简单的shell脚本如下:

#!/bin/bash
echo "hello world!"

运行shell脚本的两种方式:

  1. 作为可执行程序
    chmod +x ./test.sh	#赋予权限
    ./test.sh   #执行脚本
    #注意,一定要写成 ./test.sh,而不是 test.sh,即告诉编译器在当前目录执行test.sh!
  2. 作为解释器参数
    /bin/sh test.sh

    这种方式运行的脚本,不需要在第一行指定解释器信息,写了也没用。

变量

命名

变量命名时需要注意变量名和等号之间不能有空格,这点和其它编程语言都不一样。

显式赋值:

var=123

隐式赋值:

for file in `ls /etc`

for file in $(ls /etc)

使用

使用一个定义过的变量,只要在变量名前面加美元符号即可!

var=123
echo $var
echo ${var}

变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,比如下面这种情况:

for skill in Ada Coffe Action Java; do
    echo "I am good at ${skill}Script"
done

如果不给skill变量加花括号,写成echo "I am good at $skillScript",解释器就会把$skillScript当成一个变量(其值为空),代码执行结果就不是我们期望的样子了。

推荐给所有变量加上花括号,这是个好的编程习惯。

readonly

使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。

#!/bin/bash
var=123
echo ${var}
readonly var
var=456
echo ${var}

删除

使用 unset 命令可以删除变量。

变量被删除后不能再次使用。unset 命令不能删除只读变量。

类型

shell存在三种变量类型:

  1. 局部变量:局部变量在脚本或命令中定义,仅在当前shell实例中有效。
  2. 环境变量:所有的程序,包括shell启动的程序,都能访问环境变量。
  3. shell变量:由shell程序设置的特殊变量,包括局部变量和全局变量。

字符串

定义

字符串可以用单引号,也可以用双引号,也可以不用引号。

  • 单引号里的任何字符都回原样输出;单引号字符串中的单引号必须成对出现。
  • 双引号里可以出现变量和转义字符。
#!/bin/bash
name='bob'
str='this is $name'
echo ${str}
str="this is $name"
echo ${str}

s输出结果为:

➜  shell ./3_str.sh
this is $name
this is bob

拼接

name="zhangzhen"
#使用双引号拼接
a="hello,"$name""
b="hello,${name}"
#使用单引号拼接
c='hello,'$name''
d='hello,${name}'
echo $a $b $c $d

输出结果:

hello,zhangzhen hello,zhangzhen hello,zhangzhen hello,${name}

长度

str="hi,jerk morning!!"
echo ${#str}	  #输出17
expr length "$str" #输出17,因为str字符串中含有空格,因此需要添加双引号

截取

shell截取字符串通常有两种方式:从指定位置开始截取和从指定字符(子字符串)开始截取。

从指定位置开始截取:

#!/bin/bash
str="ilovefish"
echo ${str:1:4}  #love
echo ${str:4}    #efish
echo ${str:0-4:3}    #fis
echo ${str:0-4}  #fish

str:1:4表示从第二个字符开始,截取四个字符,故输出love

str:4表示从第四个字符开始到最后。

str:0-4:3表示从倒数第4个开始,往后截取3个字符。

str:0-4表示从倒数第4个开始到最后。

从指定字符开始截取:

var="http://www.baidu.com/1.html"
echo ${var#*//}	    #www.baidu.com/1.html
echo ${var##*/}	    #1.html
echo ${var%/*}      #http://www.baidu.com
echo ${var%%/*}     #http:

# 号是运算符,*// 表示从左边开始删除第一个 // 号及左边的所有字符。

##*/ 表示从左边开始删除最后(最右边)一个 / 号及左边的所有字符。

%/* 表示从右边开始,删除第一个/ 号及右边的字符。

%%/* 表示从右边开始,删除最后(最左边)一个 / 号及右边的字符。

借助shell命令做字符串截取:

var="http://www.baidu.com/123.com"
echo $var | cut -c1-4   #http
echo $var | cut -c8-    #www.baidu.com/123.com
echo $var | cut -d ":" -f 1 #http

查找

str="ilove china"
echo `expr index "$str" io`

查找字符 io 的位置(哪个字母先出现就计算哪个)

数组

bash支持一维数组(不支持多维数组),并且没有限定数组的大小。

定义

数组名=(值1 值2 ....)
arr=(1 2 3 4)
arr=(
1
2
3
4
)
arr[0]=1
arr[1]=2
...

读取

echo ${arr[0]}

长度

length=${#arr[@]}        #获取元素个数
length=${#arr_name[*]}   #获取元素个数
length=${#arr[n]}        #获取单个元素的长度
#!/bin/bash

arr=(1 2 3 "hello")
echo ${arr[3]} #hello
length1=${#arr[*]}
length2=${#arr[@]}
length3=${#arr[3]}
echo ${length1} $length2 $length3 # 4 4 5

注释

#

单行注释。

EOF

多行注释。

:<<EOF
注释内容...
...
EOF

注意,注释符号EOF可以使用其他符号,如'!


参数

传递参数

我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$nn 代表执行脚本的第n个参数。

如下实例:

#!/bin/bash

echo "Shell传参实例!"
echo "执行的文件名:$0"
echo "第一个参数:$1"
echo "第二个参数:$2"

执行结果如下:

➜  shell ./5_para.sh 1 2
Shell传参实例!
执行的文件名:./5_para.sh
第一个参数:1
第二个参

参数处理

以下,可以使用一些特殊字符来处理参数:

参数处理 说明
$# 传递到脚本的参数个数
$* 以一个单字符串显示所有向脚本传递的参数。 如”$*”用「”」括起来的情况、以”$1 $2 … $n”的形式输出所有参数。
$$ 脚本运行的当前进程ID号
$! 后台运行的最后一个进程的ID号
$@ 与$*相同,但是使用时加引号,并在引号中返回每个参数。 如”$@”用「”」括起来的情况、以”$1” “$2” … “$n” 的形式输出所有参数。
$- 显示Shell使用的当前选项,与set命令功能相同。
$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
#!/bin/bash

echo "Shell传参示例!"
echo "第一个参数为:$1"
echo "参数个数为:$#"
echo "参数为:$*"

执行结果为:

➜  shell ./5_para_1.sh 1 2 3 4 5
Shell传参示例!
第一个参数为:1
参数个数为:5
参数为:1 2 3 4 5

$* 与 $@ 区别:

  • 相同点:都是引用所有参数。
  • 不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,,则 “ * “ 等价于 “1 2 3”(传递了一个参数),而 “@” 等价于 “1” “2” “3”(传递了三个参数)。
#!/bin/bash

echo "-- \$*演示 --"
for i in "$*"; do
        echo $i
done
echo "-- \$@演示 --"
for i in "$@"; do
        echo $i
done

执行结果如下:

➜  shell ./5_para_2.sh 1 2 3
-- $*演示 --
1 2 3
-- $@演示 --
1
2
3

中括号

Shell 里面的中括号(包括单中括号与双中括号)可用于一些条件的测试:

  • 算术比较, 比如一个变量是否为0, [ $var -eq 0 ]
  • 文件属性测试,比如一个文件是否存在,[ -e $var ], 是否是目录,[ -d $var ]
  • 字符串比较, 比如两个字符串是否相同, [[ $var1 = $var2 ]]

算术比较

对变量或值进行算术条件判断:

[ $var -eq 0 ]  # 当 $var 等于 0 时,返回真
[ $var -ne 0 ]  # 当 $var 不等于 0 时,返回真

需要注意的是 [ 与 ] 与操作数之间一定要有一个空格,否则会报错。比如下面这样就会报错:

[$var -eq 0 ]  或 [ $var -ne 0]
操作符 意义
-gt 大于
-lt 小于
-ge 大于或等于
-le 小于或等于

可以通过 -a (and) 或 -o (or) 结合多个条件进行测试:

[ $var1 -ne 0 -a $var2 -gt 2 ]  # 使用逻辑与 -a
[ $var1 -ne 0 -o $var2 -gt 2 ]  # 使用逻辑或 -o

文件属性测试

使用不同的条件标志测试不同的文件系统属性。

操作符 意义
[ -f $file_var ] 变量 $file_var 是一个正常的文件路径或文件名 (file),则返回真
[ -x $var ] 变量 $var 包含的文件可执行 (execute),则返回真
[ -d $var ] 变量 $var 包含的文件是目录 (directory),则返回真
[ -e $var ] 变量 $var 包含的文件存在 (exist),则返回真
[ -c $var ] 变量 $var 包含的文件是一个字符设备文件的路径 (character),则返回真
[ -b $var ] 变量 $var 包含的文件是一个块设备文件的路径 (block),则返回真
[ -w $var ] 变量 $var 包含的文件可写(write),则返回真
[ -r $var ] 变量 $var 包含的文件可读 (read),则返回真
[ -L $var ] 变量 $var 包含是一个符号链接 (link),则返回真

使用方法如下:

fpath="/etc/passwd"
if [ -e $fpath ]; then
  echo File exits;
else
  echo Does not exit;
fi

字符串比较

在进行字符串比较时,最好使用双中括号 [[ ]]. 因为单中括号可能会导致一些错误,因此最好避开它们。

检查两个字符串是否相同:

[[ $str1 = $str2 ]]

当 str1等于str1等于str2 时,返回真。也就是说,str1 和 str2 包含的文本是一样的。其中的单等于号也可以写成双等于号,也就是说,上面的字符串比较等效于 [[ $str1 == $str2 ]]。

注意 = 前后有一个空格,如果忘记加空格, 就变成了赋值语句,而非比较关系了。

字符串的其他比较情况:

操作符 意义
[[ $str1 != $str2 ]] 如果 str1 与 str2 不相同,则返回真
[[ -z $str1 ]] 如果 str1 是空字符串,则返回真
[[ -n $str1 ]] 如果 str1 是非空字符串,则返回真

使用逻辑运算符 && 和 || 可以轻松地将多个条件组合起来, 比如:

str1="Not empty"
str2=""
if [[ -n $str1 ]] && [[ -z $str2 ]];
then
  echo str1 is nonempty and str2 is empty string.
fi

test 命令也可以从来执行条件检测,用 test 可以避免使用过多的括号,[] 中的测试条件同样可以通过 test 来完成。

if [ $var -eq 0 ]; then echo "True"; fi

等价于:

if test $var -eq 0; then echo "True"; fi

原创文章,作者:小嵘源码,如若转载,请注明出处:https://www.lcpttec.com/shelljb/

(0)
上一篇 2019年9月30日 下午2:49
下一篇 2019年9月30日 下午2:56

相关推荐

  • CONTABO:黑色星期五优惠德国VPS

    俗话说:”便宜的vps服务器能发家致富“。今天,小编继续来推荐外贸建站服务器VPS。CONTABO:黑色星期五优惠德国VPS。 黑色星期五优惠德国VPS contabo从2003年开始运作到现在,有两处自建的独立机房,主要业务是独立服务器出租(包括设备托管),其次是VPS、虚拟主机、域名;主持银行转账、PayPal付款等方式。 商家细节介绍; KVM虚拟,1…

    2019年11月30日
    2.0K0
  • 国外VPS购买推荐帖子:HOSTSAILOR

    便宜的vps服务器能发财致富呢!国外服务器供应商HOSTSAILOR:服务器vps黑色星期五优惠价格,只需要6.6$一年哦!本方法由峰哥博客提供。工具:谷歌浏览器+谷歌浏览器上面的谷歌自动翻译。(谷歌翻译英文嘛,但博主英文好,是不需要翻译英文的,啊哈哈哈哈哈) 需要的可以上车,6.6$一年目前还有库存,无需优惠码直接购买即可! 这家除了线路比较烂其他都可以!…

    2019年11月30日
    1.8K0
  • Linux背景知识

    操作系统 体系结构 控制器:CPU,读取系统指令 运算器:CPU,运算 储存器:RAM(内部存储器:易失性存储器) 输入设备:输入数据 输出设备:显示命令执行结果 总线结构 地址总线:负责内存寻址 数据总线:负责传输数据 控制总线:负责控制指令 基本背景 前世 1969年,一群MIT BELL Lib 的家伙用汇编语言开发出一款收费操作系统:MULTICS …

    2019年9月30日
    1.7K0
  • 信息安全实验

    Day1 开班总结 以企业管理的要求约束自己:自律、慎独 做好自己,帮助他人,乐于分享,团队合作 团队 团队4人 课程计划 安装Centos7 远程访问配置 LAMP搭建与Linux+Tomacat+mysql搭建js的环境 通过shell运维网站 部署zabbix实时监控网站及服务器 部署IDS(snort)入侵检测系统 对上述网站进行渗透测试和漏洞修复 …

    2019年9月26日
    2.3K0
  • C语言

    基础 数据类型 C 中的类型可分为以下几种: 序号 类型与描述 1 基本类型: 它们是算术类型,包括两种类型:整数类型和浮点类型。 2 枚举类型: 它们也是算术类型,被用来定义在程序中只能赋予其一定的离散整数值的变量。 3 void 类型: 类型说明符 void 表明没有可用的值。 4 派生类型: 它们包括:指针类型、数组类型、结构类型、共用体类型和函数类型…

    2019年9月30日
    2.1K0
  • Windows安全之账号克隆

    账号策略 Windows中SID是标识用户、组和计算机账户的唯一号码。 使用工具getsid.exe进行获取管理员和普通用户的sid: D:>getsid \localhost administrator \localhost guest The SID for account administrator is S-1-5-21-1016001505-…

    2019年9月30日
    2.2K0
  • 漏洞复现:”CVE_2019_0708 BlueKeep”

    环境篇 Windows7 ultimate sp1 x64 MSF 开启远程桌面: 关闭防火墙: 利用篇 早期蓝屏 这是早期漏洞利用POC! git clone https://github.com/n1xbyte/CVE-2019-0708.git cd CVE-2019-0708 pip3 install impacket python3 crashpo…

    2019年9月26日
    3.7K0
  • 关于宝塔面板良心插件Nginx防火墙免费版

    有人在宝塔官方论坛发布了一款宝塔面板Nginx防火墙免费版。可以使用在centos、debian、ubuntu系统的宝塔面板里。使用逻辑基本和官方版一样(可以说基本相同)。不知道官方能让这个插件存活多久。 安装方式,宝塔面板7.0.2版本。找到软件商店 – 第三方应用 – Nginx防火墙免费版1.0。安装即可。 让我们来看看界面 看了以上界面,是不是感觉非…

    2019年11月15日
    1.4K0
  • 仿站工具:一键就能下载网页模板

    这次,小编来给大家推荐一下 ”仿站工具“,”仿站工具“:一键就能下载网页模板。好使,方便,实用。 看到人家好看的网站主题模板想要怎么办?自己又不懂代码又不想花钱请人来写怎么办?接下来分享一个自用的“扒站神器”(单页面扒站工具)输入目标网站网址点击两下就可以把想要的模板网页下载下来。 平时自己收藏使用的免费分享给大家。 仿站工具 仿站(扒站)工具介绍 仿站小工…

    2019年12月15日
    2.5K0
  • Linux命令

    查看 uname 查看系统相关信息 常用命令选项 -a: 显示主机名、内核版本、硬件平台等详细信息 -r: 显示内核版本 示例 [root@rh-6 ~]# uname -r 2.6.32-220.el6.i686 查看CPU信息 /proc/cpuinfo 示例 [root@rh-6 ~]# cat /proc/cpuinfo processor : 0 …

    2019年9月30日
    1.6K0
  • Google Hacking

    基础技术 特殊字符 *:指代任意内容 + / -:强制(不)搜索+ / -后面的内容,不得有空格 “”:强制搜索””内部包含的内容 ():Google对()不敏感,但可以帮助使用者明确搜索语法,如intext:(password|passcode) intext:(username|userid)与intext:password | passcode int…

    2019年9月26日
    2.2K0
  • 推荐一款网络推广营销拓客的软件

    这次,小编来给大家推荐一款网络推广营销拓客的软件。希望对做网站推广的小伙伴们有所帮助哦。 为各位互联网营销及SEO站长朋友们推荐一款《站长拓客营销神器》,苦苦寻找很久终于给开发出来了,为网络营销从业者朋友解决双手,让获客成本和流量变成更加高效。 什么是“无忧拓客营销” 软件名称:无忧拓客营销工具,名字是我自己起的,帮助网站长们快速挖掘行业流量网站,拓展网站流…

    2019年12月15日
    2.4K0