Linux之Shell编程

前言

这几年一直在it行业里摸爬滚打,一路走来,不少总结了一些python行业里的高频面试,看到大部分初入行的新鲜血液,还在为各样的面试题答案或收录有各种困难问题

于是乎,我自己开发了一款面试宝典,希望能帮到大家,也希望有更多的Python新人真正加入从事到这个行业里,让python火不只是停留在广告上。

微信小程序搜索:Python面试宝典

或可关注原创个人博客:https://lienze.tech

也可关注微信公众号,不定时发送各类有趣猎奇的技术文章:Python编程学习

Shell编程

曾经有人说过,学习Linux不知道Shell编程,那就是不懂Linux,现在细细品味确实是这样。Shell是操作系统的最外层,Shell可以合并编程语言以控制进程和文件,以及启动和控制其它程序。

Shell 通过提示您输入,向操作系统解释该输入,然后处理来自操作系统的任何结果输出,简单来说Shell就是一个用户跟操作系统之间的一个命令解释器。

Shell是用户与Linux操作系统之间沟通的桥梁,用户可以输入命令执行,又可以利用 Shell脚本编程去运行


Linux Shell种类非常多,常见的SHELL如下:

  • 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由于易用和免费,在日常工作中被广泛使用,也是大多数Linux操作系统默认的Shell环境。

Shell、Shell编程、Shell脚本、Shell命令之前都有什么区别呢?简单来说Shell是一个整体的概念,Shell编程与Shell脚本统称为Shell编程,Shell命令是Shell编程底层具体的语句和实现方法

HELLO-WORLD

Shell脚本编程需要如下几个事项:

  • Shell脚本名称命名一般为英文、大写、小写;
  • 不能使用特殊符号、空格来命名;
  • Shell脚本后缀以.sh结尾;
  • 不建议Shell命名为纯数字,一般以脚本功能命名。
  • Shell脚本内容首行需以#!/bin/bash开头;
  • Shell脚本中变量名称尽量使用大写字母,字母间不能使用“-”,可以使用“_”;
  • Shell脚本变量名称不能以数字、特殊符号开头。

#!/bin/bash  							固定格式,定义该脚本所使用的Shell类型
#This is my First shell 	#号表示注释,没有任何的意义,SHELL不会解析它
echo  “Hello  World ” 		Shell脚本主命令,执行该脚本呈现的内容

Shell脚本编写完毕,如果运行该脚本,运行用户需要有执行权限,可以使用chmod o+x first_shell.sh赋予可执行权限

然后./first_shell.sh执行即可,还可使用命令执行/bin/sh first_shell.sh直接运行脚本,不需要执行权限,最终脚本执行显示效果一样

SHELL-注释

  • # 开头的行就是注释,会被解释器忽略
  • 多行注释可以使用EOF
:<<EOF
注释内容...
注释内容...
注释内容...
EOF
:<<'
注释内容...
注释内容...
注释内容...
'
:<<!
注释内容...
注释内容...
注释内容...
!

SHELL-括号

用于多个命令组、命令替换、初始化数组

if (date);
# 类似 `cmd`

整数扩展、运算符、重定义变量值,算术运算比较

(( 1==1 ))
(( 1+1 ))
(( a++ ))
for (( i=0;i<5;i++ ))
if [];	# bash内部命令,[与test是等同的,正则字符范围、引用数组元素编号,不支持+-*/数学运算符,逻辑测试使用-a、-o
if [[ ]];	# bash程序语言的关键字,不是一个命令,[[ ]]结构比[ ]结构更加通用,不支持+-*/数学运算符,逻辑测试使用&&、||
if {}; # 主要用于命令集合或者范围,例如mkdir  -p  /data/201{7,8}/
{1..5}
{1,5}

SHELL-变量

Shell变量是非类型的解释型语言,不像C++、JAVA语言编程时需要事先声明变量,Shell给一个变量赋值,实际上就是定义了变量

在Linux支持的所有shell中,都可以用赋值符号(=)为变量赋值

Shell变量为弱类型,定义变量不需要声明类型,但在使用时需要明确变量的类型,可以使用Declare指定类型,Declare常见参数有

+/-  "-"可用来指定变量的属性,"+"为取消变量所设的属性;
-f  仅显示函数;
r  将变量设置为只读;
x  指定的变量会成为环境变量,可供shell以外的程序来使用;
i  指定类型为数值,字符串或运算式。

Shell编程中变量分为三种,分别是系统变量、环境变量和用户变量

  • 系统变量在对参数判断和命令返回值判断时使用

  • 环境变量则主要是在程序运行时需要设置

  • 用户变量又称为局部变量,多使用在Shell脚本内部或者临时局部使用


  • 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
  • 中间不能有空格,可以使用下划线(_)。
  • 不能使用标点符号。
    • 不能使用bash里的关键字(可用help命令查看保留关键字)
#!/bin/bash
var=abc
echo "this is $var"
  • 注意:赋值语句必须挨着=号
for skill in Ada Coffe Action Java; do
    echo "I am good at ${skill}Script"
done

花括号也可以用来隔离变量与字符

系统变量

SHELL编程常见系统变量

$0 							   当前脚本的名称;
$n 							   当前脚本的第n个参数,n=1,2,…9;
$* 							   当前脚本的所有参数(不包括程序本身)$# 							   当前脚本的参数个数(不包括程序本身)$? 							   命令或程序执行完后的状态,返回0表示执行成功;
$$ 							   程序本身的PID号。
环境变量

SHELL编程常见环境变量

$PATH  							命令所示路径,以冒号为分割;
$HOME  							打印用户家目录;
$SHELL 							显示当前Shell类型;
$USER  							打印当前用户名;
$ID    							打印当前用户id信息;
$PWD   							显示当前所在路径;
$TERM  							打印当前终端类型;
$HOSTNAME      			显示当前主机名。
用户变量

SHELL编程用户变量

A=123												    #自定义变量A;
N_SOFT=nginx-1.12.0.tar.gz  		#自定义变量N_SOFT;
BACK_DIR=/data/backup/      	  #自定义变量BACK_DIR;
IP1=192.168.1.11								#自定义变量IP1;
IP2=192.168.1.12								#自定义变量IP2。

SHELL-变量操作

只读变量

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

myUrl="https://www.google.com"
readonly myUrl
删除变量

使用 unset 命令可以删除变量,unset 命令不能删除只读变量

unset variable_name

SHELL-运算

Shell 和其他编程语言一样,支持多种运算符

  • 算数运算符
  • 关系运算符
  • 布尔运算符
  • 字符串运算符
  • 文件测试运算符

原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。

expr 是一款表达式计算工具,使用它能完成表达式的求值操作

#!/bin/bash

val=`expr 2 + 2`
echo "两数之和为 : $val"
算数运算符
运算符说明举例
+加法expr $a + $b 结果为 30。
-减法expr $a - $b 结果为 -10。
*乘法expr $a \* $b 结果为 200。
/除法expr $b / $a 结果为 2。
%取余expr $b % $a 结果为 0。
=赋值a=$b 将把变量 b 的值赋给 a。
==相等。用于比较两个数字,相同则返回 true。[ $a == $b ] 返回 false。
!=不相等。用于比较两个数字,不相同则返回 true。[ $a != $b ] 返回 true。
关系运算符
运算符说明举例
-eq检测两个数是否相等,相等返回 true。[ $a -eq $b ] 返回 false。
-ne检测两个数是否不相等,不相等返回 true。[ $a -ne $b ] 返回 true。
-gt检测左边的数是否大于右边的,如果是,则返回 true。[ $a -gt $b ] 返回 false。
-lt检测左边的数是否小于右边的,如果是,则返回 true。[ $a -lt $b ] 返回 true。
-ge检测左边的数是否大于等于右边的,如果是,则返回 true。[ $a -ge $b ] 返回 false。
-le检测左边的数是否小于等于右边的,如果是,则返回 true。[ $a -le $b ] 返回 true。
布尔运算符
运算符说明举例
!非运算,表达式为 true 则返回 false,否则返回 true。[ ! false ] 返回 true。
-o或运算,有一个表达式为 true 则返回 true。[ $a -lt 20 -o $b -gt 100 ] 返回 true。
-a与运算,两个表达式都为 true 才返回 true。[ $a -lt 20 -a $b -gt 100 ] 返回 false。
逻辑运算符
运算符说明举例
&&逻辑的 AND[[ $a -lt 100 && $b -gt 100 ]] 返回 false
||逻辑的 OR[[ $a -lt 100 || $b -gt 100 ]] 返回 true
字符串运算符
运算符说明举例
=检测两个字符串是否相等,相等返回 true。[ $a = $b ] 返回 false。
!=检测两个字符串是否相等,不相等返回 true。[ $a != $b ] 返回 true。
-z检测字符串长度是否为0,为0返回 true。[ -z $a ] 返回 false。
-n检测字符串长度是否不为 0,不为 0 返回 true。[ -n “$a” ] 返回 true。
$检测字符串是否为空,不为空返回 true。[ $a ] 返回 true。
文件测试运算符
操作符说明举例
-b file检测文件是否是块设备文件,如果是,则返回 true。[ -b $file ] 返回 false。
-c file检测文件是否是字符设备文件,如果是,则返回 true。[ -c $file ] 返回 false。
-d file检测文件是否是目录,如果是,则返回 true。[ -d $file ] 返回 false。
-f file检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。[ -f $file ] 返回 true。
-g file检测文件是否设置了 SGID 位,如果是,则返回 true。[ -g $file ] 返回 false。
-k file检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。[ -k $file ] 返回 false。
-p file检测文件是否是有名管道,如果是,则返回 true。[ -p $file ] 返回 false。
-u file检测文件是否设置了 SUID 位,如果是,则返回 true。[ -u $file ] 返回 false。
-r file检测文件是否可读,如果是,则返回 true。[ -r $file ] 返回 true。
-w file检测文件是否可写,如果是,则返回 true。[ -w $file ] 返回 true。
-x file检测文件是否可执行,如果是,则返回 true。[ -x $file ] 返回 true。
-s file检测文件是否为空(文件大小是否大于0),不为空返回 true。[ -s $file ] 返回 true。
-e file检测文件(包括目录)是否存在,如果是,则返回 true。[ -e $file ] 返回 true。

SEHLL-字符串

字符串是shell编程中最常用最有用的数据类型(除了数字和字符串,也没啥其它类型好用了)

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

单引号
str='this is a string'
  • 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的
  • 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用
双引号
your_name='fuck'
str="Hello, I know you are \"$your_name\"! \n"
echo -e $str
  • 双引号里可以有变量
  • 双引号里可以出现转义字符
获取长度
string="abcd"
echo ${#string} # 输出 4
提取子字符串
string="hello world"
echo ${string:1:4}
查看子字符串

查找字符串出现的位置

string="abcdesfg"
echo `expr index "$string" s` 

SHELL-数组

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

类似于 C 语言,数组元素的下标由 0 开始编号

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

array_name=(value0 value1 value2 value3)

array_name=(
value0
value1
value2
value3
)

array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen
访问数组
  • 索引访问某个
${数组名[下标]}
  • 访问全部
echo ${array_name[@]}
echo ${array_name[*]}
获取数组长度
# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
lengthn=${#array_name[n]}

SHELL-IF

Linux Shell编程中,if、for、while、case等条件流程控制语句用的非常多

熟练掌握以上流程控制语句及语法的实验,对编写Shel脚本有非常大的益处


If条件判断语句,通常以if开头,fi结尾。也可加入else或者elif进行多条件的判断,if表达式如下

if (表达式); then
		语句1
else
		语句2
fi

  • 比较两数大小
#!/bin/bash
NUM=100
if  (( $NUM > 4 )); then 
		echo "The  Num  $NUM  more  than 4."
else
		echo "The  Num  $NUM  less   than 4."
fi

num1=10
if (( $num1 + 10 > 20 ))
then
    echo "1"
else
    echo "2"
fi
  • 判断目录是否存在
#!/bin/bash
if  [  !  -d  /data/20140515  -a  !  -d  /tmp/2017/  ]; then 
		mkdir  -p  /data/20140515
fi

  • 常见逻辑运算符
if [ -f filename ];		# -f判断文件是否存在
if [ -d dir];					# -d判断目录是否存在
---------------------------------------------
-eq										# 等于判断,应用于整形比较
-ne										# 不等于,应用于整形比较
-lt										#	小于,应用于整形比较
-gt										# 大于,应用于整形比较
-le										# 小于或等于,应用于整形比较
-ge										# 大于或等于,应用于整形比较
---------------------------------------------
-a				# 前后条件都成立,and
-o				# 前后条件有一成立,or	
-z				# 空字符串
||				# or
&&				# and

SHELL-FOR

  • 语法
for var in item1 item2 ... itemN
do
    command1
    command2
    ...
    commandN
done
for var in item1 item2 ... itemN; do command1; command2… done;
  • demo
for str in 'This is a string'
do
    echo $str
done
for str in 1 2 3
do
    echo -e "$str\n"
done

  • 循环打印1至100数字,seq表示列出数据范围
for num in `seq 1 100`
do
    echo -e "$num"
done
  • 1-100求和
#!/bin/bash
j=0
for ((i=1; i<=100; i++))
do
    j=`expr $i + $j`
done
echo $j

SEHLL-WHILE

While循环语句与for循环功能类似,主要用于对某个数据域进行循环读取、对文件进行遍历

通常用于需要循环某个文件或者列表,满足循环条件会一直循环,不满足则退出循环

其语法格式以while…do开头,done结尾。语法格式如下

while condition
do
    command
done

  • 1-100求和
#!/bin/bash
j=0
i=1
while ((i<=100))
do
     j=`expr $i + $j`
     ((i++))
done
echo $j
  • 读取文件
while read line
do
		echo $line
done  <  filename
for  line  in  `cat filename`
do
		echo ${line}
done
  • 无限循环
while :
do
    command
done
while true
do
    command
done

SHELL-CASE

Shell case语句为多选择语句。可以用case语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令

  • 语法
casein
模式1)
    command1
    ;;
模式2)
    command1
    ;;
esac

  • demo
echo '输入 1 到 4 之间的数字:'
echo '你输入的数字为:'
read aNum
case $aNum in
    1)  echo '你选择了 1'
    ;;
    2)  echo '你选择了 2'
    ;;
    3)  echo '你选择了 3'
    ;;
    4)  echo '你选择了 4'
    ;;
    *)  echo '你没有输入 1 到 4 之间的数字'
    ;;
esac

SHELL-SELECT

Select语句一般用于选择,常用于选择菜单的创建

其语法格式以selct…in do开头,done结尾

  • 语法
select i in (表达式) 
do
		command
done

  • 输出菜单
PS3="What you like most of the open source system?"
select i in CentOS RedHat Ubuntu 
do
		echo "Your Select System: "$i
done

SHELL-break

break命令允许跳出所有循环,终止执行后面的所有循环

#!/bin/bash
while :
do
    echo -n "输入 1 到 5 之间的数字:"
    read aNum
    case $aNum in
        1|2|3|4|5) echo "你输入的数字为 $aNum!"
        ;;
        *) echo "你输入的数字不是 1 到 5 之间的!"
            break
        ;;
    esac
done

SHELL-continue

跳出当前循环

#!/bin/bash
while :
do
    echo -n "输入 1 到 5 之间的数字:"
    read aNum
    case $aNum in
        1|2|3|4|5) echo "你输入的数字为 $aNum!"
        ;;
        *) echo "你输入的数字不是 1 到 5 之间的!"
            continue
        ;;
    esac
done

SHELL-函数

shell支持函数定义,可以实现代码封装复用

[ function ] funname [()]
{
    action;
    [return int;]
}
function helloworld(){
		echo "hello world"
}
helloworld # 调用函数无须加括号

  • 判断IP
judge_ip(){
		read -p "Please enter ip Address,example 192.168.0.11 ip": IPADDR
    echo $IPADDR|grep -v "[Aa-Zz]"|grep --color -E "([0-9]{1,3}\.){3}[0-9]{1,3}"
}
judge_ip
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李恩泽的技术博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值