Shell学习记录

Shell简介

shell是外壳的意思,就是操作系统的外壳。我们可以通过shell命令来操作和控制操作系统,比如Linux中的Shell命令就包括ls、cd、pwd等等。总结来说,Shell是一个命令解释器,它通过接受用户输入的Shell命令来启动、暂停、停止程序的运行或对计算机进行控制。

shell 是一个应用程序,它连接了用户和 Linux 内核,让用户能够更加高效、安全、低成本地使用 Linux 内核,这就是 Shell 的本质。

shell 本身并不是内核的一部分,它只是站在内核的基础上编写的一个应用程序。

shell脚本就是由Shell命令组成的执行文件,将一些命令整合到一个文件中,进行处理业务逻辑,脚本不用编译即可运行。它通过解释器解释运行,所以速度相对来说比较慢。

shell脚本中最重要的就是对shell命令的使用与组合,再使用shell脚本支持的一些语言特性,完成想要的功能。

注释

#:开头的就是注释,被编译器忽略

单行注释: #
多行注释: :<<EOF … EOF 或者 :<<! … ! (:<< 标识多行注释开始,并指定一个标识符作为开始结束的标志)

变量

变量类型

运行shell时会有三种变量

  • 局部变量:在脚本或者命令中定义,只在当前实例中使用,别的shell脚本启动的程序无法访问
  • 环境变量:所有程序都能访问环境变量
  • shell变量:shell变量是由shell程序设置的变量,shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行

变量操作

  • 创建普通变量:name=“test” # '='两边不可以有空格
  • 创建局部变量:local name=“test”
  • 使用变量 :echo ${name}
  • 变量重新赋值:name=“newname”
  • 只读变量:name=“test_rdonly”->readonly name 使用readonly标识后的变量,不可被修改
  • 删除变量:unset name #删除之后这个变量就不可访问,不能删除只读变量

字符串变量

单引号
  • var='test' 只能原样的输出,字符串中加的变量是无效的
  • 而且单引号变量中不能出现单个的单引号,即使转义也是无效的
双引号
  • var="my name is ${name}" 双引号变量中的使用的变量是有效的
  • 在双引号变量中,可以出现转义符
字符串的拼接

字符串中间不用加+号

var="this is ""my name "
var="this"is"my name"
var="this is my name"

以上三种写法是一样的(双引号换成单引号同理)

获取字符串的长度
  • 在${}中使用#获取字符串长度
name="test";
echo ${#name};
#输出结果为4
提取子字符串

e.g.

var="this is my name";
#1:4 -> 从第2个字符开始向后取4个字符
#::4 -> 从第1个字符开始向后取4个字符
echo ${var1:4} #输出结果 = his 
echo ${var::4} #输出结果 = this 

数组

注意:BASH只支持一维数组,不支持多维数组

array_name=(liu yao wen); #用小括号做边界,空格分隔
  • 赋值数组元素
array_name[0]="liu";

-获取数组元素

echo ${array_name[0]};
#输出liu
echo ${array_name[@]};
#输出所有元素
  • 获取数组长度
echo ${#array_name[@]};
#输出元素个数
echo ${#array_name[0]};
#输出liu的长度

参数传递

$$ #输出当前进程号
$! #输出后台运行的最后一个进程ID
$? #输出最后命令的退出状态
$# #输出参数个数
$* #输出参数-----格式:“$1,$2.....”
$@ #输出参数-----格式:“$1”,“$2”,“$3”

运算符

算术运算

  • +、-、* 、/ 注意:乘法 * 必须用转义符\转义后使用
var=`expr 2+2`;   #Linux使用expr辅助运算
var=$[2+2];
var=$((2+2));

数字关系运算符

关系运算符只支持数字,不支持字符串

a=2;
b=3;
------------------------------
#-eq:判断相等
[$a -eq $b] ; #返回false

#-ne:判断是否不相等
[$a -ne $b]; #返回true

#-gt : 左 大于 右
[$a -gt $b]; #返回false

#-lt: 左 小于 右
[$a -lt $b]; #返回true

#-ge :左 大于等于 右
[$a -ge $b]; #返回flase

#-le :左 小于等于 右
[$a -le $b]; #返回true

字符串运算符

a='abc';
b='edg';

# = 判断字符串是否相等
[$a = $b]; #返回flase

# != 判断是否不相等
[$a != $b]; #返回true

# -z 判断字符串长度是否为0
[-z $a]; #返回false

# -n 判断字符串长度是否不为0
[-n $a]; #返回true

# $ 判断字符串长度是否为空,不为空返回true
[$a]; #返回true

布尔运算符

a=10;
b=20;

# !:非,表达式为 true 则返回 false,否则返回 true。 [ ! false ] 返回 true。

# -o : 或运算
[$a -lt $b -o $a -gt $b]; #返回true

#-a : 与运算
[-z $a -a $a -lt $b]; #返回false

逻辑运算符

a=10;
b=20;

# && : 与
[[$a -lt 100 && $b -gt $a]]; #返回true

# || :或
[[$a -lt 5 || $a -lt $b]]; #返回true

文件运算符

-b : 判断文件是否是块设备文件
-c : 判断文件是否是字符设备文件
-d : 判断文件是否是目录文件
-f : 判断文件是否是普通文件
-r : 判断文件是否可读
-w : 判断文件是否可写
-x : 判断文件是否可执行
-p : 判断文件是否是有名管道
-s : 判断文件是否为空,不为空返回true
-e : 判断文件是否存在

执行相关

命令替换

命令替换与变量替换差不多,都是用来重组命令行的,先完成引号里的命令行,然后将其结果替换出来,再重组成新的命令行

执行命令

`ls /etc` ; #反引号适用于所有unix系统
$(ls /etc); #部分unix系统不适用.多个嵌套时,由内向外执行

算数运算

$[];
$(());

逻辑判断

() 中括号旁边和运算符两边必须添加空格 不推荐使用 
[[]] 中括号旁边和运算符两边必须添加空格 ---字符串比较式
(()) 中括号旁边和运算符两边必须添加空格 ---数学比较式
(())[[]]()针对算数比较式和字符串比较式的加强版
[[]] 中可以保证 && || 的使用不出错,[]中使用&& || 会报错
(()) 中的算术运算符不需要使用转义符

输出

  • echo 仅用于字符串的输出,可以自动添加换行符,不如printf 可移植性好
  • printf 不会自动换行,可以添加\n换行
    e.g.printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234
  • s String 字符串
  • d 十进制整数
  • c 字符
  • f 浮点型
  • %-10s -10代表左对齐,宽度为10个字符(-代表左对齐,没有就是右对齐)
  • %-4.2f -4.2代表宽度为4个字符,保留小数点后两位
    转义符
  • \a :警告字符,通常为ASCII的BEL字符
  • \b :后退
  • \c :抑制(不显示)输出结果中任何结尾的换行字符(只在%b格式指示符控制下的参数字符串中有效),而且,任何留在参数里的字符、任何接下来的参数以及任何留在格式字符串中的字符,都被忽略
  • \f :换页(formfeed)
  • \n :换行
  • \r :回车(Carriage return)
  • \t :水平制表符
  • \v :垂直制表符
  • \ :一个字面上的反斜杠字符
  • \ddd :表示1到3位数八进制值的字符。仅在格式字符串中有效
  • \0ddd :表示1到3位的八进制值字符

流程控制

if

if comdition
then
	command1
	command2
fi

if else

if condition
then 
	command1
	command2
else
	command3
	command4
fi

if else-if else

if condition1
then
	command1
	command2
elif condition2
then
	command3
	command4
else
	command5
fi

for

for var in item1 item2....itemN
do
	command1
	command2
done

while

while condition
do 
	command1
done

特殊情况:

无限循环 ---- 加冒号
while:
do 
	command1
done

util

util condition
do 
	command
done	

case

Shell case语句为多选择语句。可以用case语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。
case需要一个esac(就是case反过来)作为结束标记,每个case分支用右圆括号,用两个分号表示break,其中“;;”不是跳出循环,是不在去匹配下面的模式

case 值 in
	case1)
		command
		;;
	case2)
		command
		;;
	...
esac

中断

break : 跳出循环
continue : 结束此次循环,继续下一次

定义函数

[function] funname()
{
	action;
	[return int;]
}

调用函数

function funname()
{
	echo "第一个参数为$1";
	echo"第二个参数为$2";
	echo "共有$#个参数";
	echo "作为一个字符串输出所有参数$*";
	#$@是“1”“2”“3”;$*是“123”
}

#调用函数
funnanme 1,2;

#判断是否成功调用函数
echo $?;
函数返回值

return可加可不加,如果加,只能返回0~255中的整型;
函数中如果不加return[0~255],默认成功执行返回0;
如果加了return值,那么return值就作为成功执行后返回的值,$?返回的就是这个值;

输入输出重定向

一般情况下,每个unix和Linux命令执行时都会打开三个文件:

  • 标准输入文件 stdin 文件描述符为0
  • 标准输出文件 stdout 文件描述符为1
  • 标准错误文件 stderr 文件描述符为2,Unix默认向stderr中写入错误信息

command>file:将输出重定向至文件中
command<file:将输入重定向至文件
如果不想将执行结果输出,可以将输出重定向至/dev/null

bash.sh > file;
#输出到file中,--覆盖数据
bash.sh >> file;
#输出到file中,--追加数据

bash.sh < file;
#从file中读数据

command >> file 2&1;
#将stdout 和stderr中的内容合并重定向到file中
读取外部输入

命令:read arg
在执行这条指令时,shell脚本暂停执行等待外部输入,将外部输入值送到变量上

文件引用

文件引用有2中方法:

.filepath\filename
-----------------------------
sourse filepath\filename
长句换行

使用 ’ \ ‘ 换行

  • 换行后按照一行一个语句执行,与直接回车换行不同
  • 注意:在使用时,\前加空格,\后不用加空格
退出脚本

命令:exit
一般情况下,shell脚本正常退出:exit0
推出出现错误:exit 1

命令:set -eset +e
set -e :表示从当前位置开始,一旦遇到错误立刻触发exit
set +e:表示郑出现什么错误,都不会exit,会把命令执行完

如果脚本是有状态的(每个后续步骤都依赖前一个步骤),那么请使用set -e,在脚本出现错误时立即退出脚本。
如果要求所有命令都要执行完(很少会这样),那么就使用set +e。

调试脚本

检查是否有语法错误:bash -n test.sh
调试脚本:bash -x test.sh

shell操作MySQL

-u 用户名
-p 用户密码
-h 服务器ip地址
-D 连接的数据库
-N 不输出列信息
-B 使用tab键 代替 分隔符
-e 执行的SQL语句

e.g.

/mysql/mysql/bin/mysql\
	-h host -p 000
	-u user_name -p password
	-e"use database; select * from database;"#-e代表执行sql语句

案例

调试脚本案例

#!/usr/bin.env bash

# 用于计算数组中奇数的和
# @author liyangyang
# @time 2019/09/17

sum=0
for num in 1 2 3 4;do
    re=${num}%2
    if (( ${re} == 1 ));then
        sum=$[${sum}+${num}]
    fi
done
echo ${sum}

首先,检查语法错误bash -n test.sh
在这里插入图片描述
没有输出,说明没有语法错误
接下来调试脚本bash -x test.sh
在这里插入图片描述
这里可以看到出现了错误,考虑之后找到原因,原因是我在for循环最后一行中num = $[${num}+${sum}]写成了${num}=$[${sum}+${num}]。等号左边使用变量,右边也使用变量,这句话的含义变成了1=2,而不是我们需要的赋值
修改后:
在这里插入图片描述
+号表示是shell调试器的输出,没有+号是程序的输出

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值