初识shell脚本

shell是什么?

Shell是一个用C语言编写的程序,它是用户使用Linux的桥梁;

Shell既是一种命令语言,又是一种程序设计语言;

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

shell脚本有sh、bash、ksh、csh、zsh等等,不同的shell脚本有自己的特点,但用法基本上是差不多的,Mac自带shell,可以用cat /etc/shells去查看,文章主要围绕bash展开。

shell脚本

一般文件后缀是.sh形式的。

哪些人需要学习shell呢?

  • Linux运维工程师:编写Shell程序进行服务集群管理
  • Python和Java程序员:编写Shell脚本程序或者是服务器的维护,比如编写一个定时备份数据库的脚本
  • 大数据程序员:编写Shell程序来管理集群
  • 前端程序员:了解shell可以更好的进行服务端开发操作

shell脚本能做什么呢?

  • 将一些复杂的命令简单化(比如我们提交一次代码可能需要很多步骤,但是可以用Shell简化成一步);
  • 解决很多重复性操作(比如多次修改相同的文件内容);
  • 自动打包、编译、发布等功能;

所以学会使用shell可以帮助我们大大的提高开发效率.

shell编写

第一行一般是这样:(指定脚本解释器)

#!/usr/bin/php
#!/usr/bin/env python3
#!/usr/bin/env bash

#!”是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行/env是系统的PATH目录中查找;告诉系统其后路径所指定的程序即是解释此脚本文件的 Shell 解释器

运行shell脚本

方式1

sh demo.sh

方式2

chmod +x demo.sh // 设置 demo.sh可执行权限
./demo.sh // 执行demo.sh

我们来编写一个简单的demo

// demo1.sh
#!/usr/bin/env bash // 从系统path中寻找指定脚本的解释程序 
echo "hello, world"

// 执行
控制台执行bash demo1.sh
// 输出:hello, world

常见语法

变量

已经定义过的变量,使用时在前面添加$,变量名外的花括号是可选的,加不加都行,建议使用第二种形式

命名
name="qiao"
使用
echo $name
echo ${name}
基础语法
  1. 定义变量: 变量名=变量值,等号两侧不能有空格,变量名一般习惯用大写
  2. 删除变量: unset 变量名
  3. 声明静态变量: readonly 变量名,静态变量不能unset
  4. 使用变量:$变量名
// 访问变量的语法形式为:${var} 和 $var
echo $myName
echo ${myName}

// 删除变量
echo ${变量名}
变量命名规则
  • 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头
  • 中间不能有空格,可以使用下划线_
  • 不能使用标点符号
  • 不能使用 bash 里的关键字
变量类型
  • 局部变量 : 仅在某个脚本内部有效的变量。不能被其他的程序和脚本访问
  • 环境变量: 对当前 shell 会话内所有的程序或脚本都可见的变量。跟创建局部变量类似,但使用的是 export 关键字,shell 脚本也可以定义环境变量;
位置参数变量
基本语法
  • $n :$1 代表命令本身、$1- 9 代 表 第 1 到 9 个 参 数 , 10 以 上 参 数 用 花 括 号 , 如 9 代表第1到9个参数,10以上参数用花括号,如 91910{10}
  • $* :命令行中所有参数,且把所有参数看成一个整体
  • $@ :命令行中所有参数,且把每个参数区分对待
  • $# :所有参数个数
注释

以“#”开头的行就是注释,会被解释器忽略。sh里没有多行注释,只能每一行加一个#号

字符串

字符串可以用单引号,也可以用双引号,也可以不用引号。Shell中常用的数据类型字符串和数字。

先来看个demo

name="qiao"
echo "my name is $name"

// 输出 my name is qiao

字符串可以使用单引号和双引号,单引号中不能包含单引号,即使转义单引号也不次那个,双引号则可以,双引号也可以使用字符串.

字符串操作
拼接字符串
name="qiao";
age="26"
echo $name $age
echo $name$age
获取字符串长度
echo ${#name}

截取字符串
echo ${name:0:2}
数组

Shell中,用括号来表示数组,数组元素用"空格"符号分割开,定义数组的一般形式为

age=(age1 age2 age3)
// 也可单独定义数组的各个值:
ary[0]=age1
ary[1]=age2
ary[3]=age3

看个demo

names=("zhang" "san" "zi")
echo ${names[0]}
echo ${names[2]}
echo ${names[@]} # @可以获取数组中的所有元素
// 输出 
zhang
zi
zhang san zi
读取数组
格式

${数组名[下标]}

echo ${age[0]}

// 使用@符号可获取数组中的所有元素
echo ${name[@]}
获取数组的长度
# 获取数组元素的个数
length=${#age[@]}
echo $length

# 或者
length=${#age[*]}
echo $length

# 取得数组单个元素的长度
lengthn=${#age[n]}
echo $length
shell参数传递

执行Shell脚本时,可以向脚本传递参数,在Shell中获取这些参数的格式为$n,即$1,$2…,

// demo2.sh
echo "第一个参数是:$1"
echo "第一个参数是:$2"
echo "第一个参数是:$3"

// 执行
bash demo2.sh 1 2 3
// 输出
第一个参数是:1
第一个参数是:2
第一个参数是:3

特殊字符处理参数:

  • $#:传递脚本的参数个数

  • $*:显示所有的参数

  • $@:返回所有参数

  • $-:显示Shell使用的当前选项

  • $?:退出的状态,0表示没有错误,其他则表示有错误

运算
算数运算

本身bash是不支持简单的数学运算的,可以借助其他命令来完成,例如awk和expr,expr最常用。expr是一款表达式计算工具,使用它能完成表达式的求值操作。算术运算符包括:+ - × / % = == !=

看个demo

// demo.sh
val=`expr 2 + 2`
echo $val

// 执行 bash demo.sh
// 输出4
注意
  • 运算符两边需要空格,且使用的是反引号
关系运算符

关系运算只支持数字,不支持字符串,除非字符串的值是数字

常见关系运算符
  • -eq:是否相等
  • -ne:是否不等
  • -gt:大于
  • -lt:小于
  • -ge:大于等于
  • -le:小于等于

看个demo

// demo.sh
a=4
b=3
if [ $a -eq $b ]
	then
	echo "相等"
else
	echo "不等"
fi

// bash demo.sh
// 输出 不等
布尔运算
  • !:非
  • -o:或
  • -a:与
逻辑运算符
  • &&:逻辑与
  • ||:逻辑或
字符串运算符
  • =:相等
  • !=:不等
  • -z:字符串长度是否为0,为0返回true [ -z $a ]
  • -n:字符串长度是否为0,不为0返回true[ -n $a ]
  • str:字符串是否为空,不为空返回true [ $a ]
文件测试运算符
属性描述写法
-b检测文件是否为块设备文件[ -b $file ]
-c检测文件是否为字符设备文件[ -c $file ]
-d检测文件是否为目录[ -d $file ]
-f检测文件是否为普通文件[ -f $file ]
-g检测文件是否设置了SGID位[ -g $file ]
-k检测文件是否设置了粘着位[ -k $file ]
-p检测文件是否是有名管道[ -p $file ]
-u检测文件是否设置了SUID位[ -u $file ]
-r检测文件是否可读[ -r $file ]
-w检测文件是否可写[ -w $file ]
-x检测文件是否可执行[ -x $file ]
-s检测文件大小是否大于0[ -s $file ]
-e检测文件是否存在[ -e $file ]

看个demo

// demo.sh
file="/Users/用户名/Desktop/shell-study/demo.sh"
if [ -e $file ]
	then
	echo "文件存在"
else
	echo "文件不存在"
fi

if [ -r $file ]
	then
	echo "可读"
else
	echo "不可读"
fi

if [ -w $file ]
	then
	echo "可写"
else
	echo "不可写"
fi

// bash demo.sh
// 输出
文件存在
可读
可写
流程判断
条件
#!/usr/bin/env bash
a=1
b=2
if [ $a == $b ]
    then
        echo "a 等于 b"
 elif [ $a -gt $b ]
    then
        echo "a大于 b"
 elif [ $a -lt $b ]
    then
        echo "a小于 b"
 else
    echo "没有符合的条件"
 fi
for循环
// 写法1
for index in 1 2 3 4 5; do
    echo "index="$index
done

// 写法2
for ((i=0; i<5; i++)); do
    echo "i="$i
done
while 语句
val=1
while(( $val<=5 ))
do
    echo $val
    let "val++"
done
case
格式:
case 值 in
模式1)
    command1
    command2
    ...
    commandN
    ;;
模式2)
    command1
    command2
    ...
    commandN
    ;;
esac

看个demo

#!/usr/bin/env bash // 从系统path中寻找指定脚本的解释程序 
echo "输入1 2 3任意一个数字"
read num
case $num in
	1)echo "输入了1"
;;
	2)echo "输入了2"
;;
	3)echo "输入了3"
;;
	*)echo "输入的值不是1 2 3"
;;
esac

// 输出
bash demo3.sh
输入1 2 3任意一个数字
1
输入了1

bash demo3.sh
输入1 2 3任意一个数字
2
输入了2

bash demo3.sh
输入1 2 3任意一个数字
3
输入了3

bash demo3.sh
输入1 2 3任意一个数字
5
输入的值不是1 2 3
函数
函数定义

自定义函数可使用或不使用function关键字,指定了return值则返回这个值,没有return语句则以最后一条运行结果作为返回值

看个demo

function fn(){
	echo "hello world"
}
// 或者
fn(){
	echo "hello world"
}
函数调用

函数名

fn
函数参数

调用函数时可以传入参数,函数内部使用;函数本身是一个命令,所以只能通过$?来获得这个返回值

#!/usr/bin/env bash // 从系统path中寻找指定脚本的解释程序
function add(){
	num=0;
	for((i=1;i<=$#;i++));
	do
		num=`expr $i + $num`
	done
	return $num
}
add 1 2 3 4 5 6 7 8 9 10
a=$?

echo $a

// bash demo.sh
// 输出: 55
输入输出重定向

使用 > 可以将echo结果写入指定文件,这就是一种输出重定向,重定向主要有以下几种:

写法描述
command > file输出重定向至文件file
command < file输入重定向至文件file
command >> file输出以追加的方式重定向至文件file
n > file将文件描述符为n的文件重定向至文件file
n >> file将文件描述符为 n 的文件以追加的方式重定向到文件file
n >& m将输出文件 m 和 n 合并
n <& m将输入文件 m 和 n 合并
<< tag将开始标记 tag 和结束标记 tag 之间的内容作为输入

常见命令

echo

用于字符串的输出

echo "hello, world"
// 输出hello, world

// 输出含变量的字符串:
name = word
echo "hello, \"${name}\""
// 输出hello, "word"

// 输出含换行符的字符串
echo "name\nage"
// 输出 name\nage

echo -e "name\nage" # -e 开启转义
#  输出
#  name
#  nage

// echo $PATH 获取系统里所有可以被直接执行程序的路径

解析转义字符

-e 参数使得 echo 可以解析转义字符

echo -e "hello \n world" # 如果不添加-e则会原样输出,添加了-e输出则会换行

使用反引号可以显示命令执行的结果,如date、pwd

echo `pwd`
echo `date`

printf

格式化输出字符串,默认情况下,printf 不会像echo自动添加换行符,如果需要换行可手动添加 \n

export

export 变量名=变量值,将Shell变量输出为环境变量

source

source 配置文件路径,让修改后的配置信息立即生效

test

检查某个条件是否成立,可以进行数值、字符、文件三方面的测试

// demo.sh
a=20
b=23
if test a == b
	then
	echo "相等"
else
	echo "不等"
fi
// bash demo.sh
// 输出:不等

grep

擅长查找功能

写法

grep [OPTIONS] PATTERN [FILE...]

这里的模式,要么是字符(串),要么是正则表达式

常见参数

参数描述
-c仅列出文件中包含模式的行数
-i忽略模式中的字母大小写
-l列出带有匹配行的文件名
-n在每一行的最前面列出行号
-v列出没有匹配模式的行
-w把表达式当做一个完整的单字符来搜寻,忽略那些部分匹配的行

看个例子

// 文件路径 filePath="/Users/用户名/Desktop/shell-study/file.js"

// 查找并打印包含"list"的行 
grep "list" ${filePath}

// 忽略大小写搜索(-i)
grep -i "list" ${filePath}

// 统计字符串出现的次数(-c)
grep -c "show" ${filePath} #17
grep -n "show" ${filePath} 
-n 可以列出匹配的字符串所在行号以及所在行内容

// 高亮显示匹配内容(--color)
grep --color "list" ${filePath}

// 双重条件匹配 匹配当前目录中包含float的文件并高亮
ls *.html | grep --color "float"
总结
  1. 单引号字符串的限制:

    单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的

    单引号字串中不能出现单引号(对单引号使用转义符后也不行)

  2. 双引号

    双引号里可以有变量

    双引号里可以出现转义字符

  3. 变量

    变量只能由大小写字母,数字和下划线组成。

    变量名称不能以数字开头;变量赋值等号两边不能有空格

    变量可以存储数字类型或者字符串类型

    字符串的变量可以用单引号或者双引号括起来

GitHub代码参考链接:https://github.com/qiaochunmei/shell-study

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值