ITPub博客

首页 > 数据库 > 数据库开发技术 > Kali Linux Shell编程基础

Kali Linux Shell编程基础

原创 数据库开发技术 作者:逍遥子 时间:2022-03-09 11:18:43 0 删除 编辑

1.1 什么是shell

Shell是LINUX内核和用户之间的解释器程序,解释器有很多种,通常是指bash,负责向内核翻译以及传达用户/程序指令。Shell 既是一种命令语言,又是一种程序设计语言。

shell的使用方式:
  1. 交互指令模式 :人工输入命令,执行效率低

  2. 非交互指令模式:使用脚本,在后台执行,需要程序员编写

我们可以选择的解释器有很多,我们通常默认的就是bash,使用cat /etc/shells可以查看电脑上有哪几种shell解释器:我这里使用的是 zsh,可以说是个性话的bash解释器。如果我们向切换解释器只需要在,命令行中输入对应的解释器即可!输入 exit就可以退出当前shell解释器,我们登录linux系统后,进入的界面就是shell解释器,我们使用pstree查看进程树我采用的是 ssh链接到服务器,由于默认的解释器是zsh ,所以一进去系统就是zsh的交互界面。如果我们此时输入 exit 退出当前解释器,那么就会自动终端我们的ssh连接。

1.2 什么是shell脚本

标准脚本的构成:
  1. 声明解释器,一般我们声明bash解释器,兼容最好,一般机器上的默认解释器#!/bin/bash
  2. 注释 脚本介绍
  3. 具体代码 ,其实就是我们的shell命令,系统会一行一行的执行
#! /bin/bashecho hello worldecho shell脚本

如何执行shell脚本

  1. 输入绝对或者相对路径 执行 ,需要脚本具有可执行权限

  2. 输入 bash [脚本名/路径] ,重新开辟一个bash解释器,执行脚本,并且执行完毕后自动退出开辟的shell脚本。无需可执行权限

  3. 输入 source 脚本名/路径 ,在当前解释器里执行脚本,执行完毕解释器状态会改变,也无需可执行权限

#! /bin/bashcd ~mkdir bash
我们输入编写一个测试脚本来验证一下后面两条:使用bash执行使用 source执行:退出shell脚本使用 exit命令即可

2. shell 语法

2.1 变量

我们可以使用set查看所有定于的变量变量的类型有如下几种:
  1. 自定义变量

  2. 环境变量

  3. 位置变量

  4. 预定义变量

  5. 自定义变量以及使用

有了变量我们写的程序更加灵活了。我们可以直接在 bash里直接设定变量,然后也可以读取它,例如:我们在自定义变量的时候,可能要求和其他编程语言语法有些不同,但是大致语法一致!
  • 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。

  • 中间不能有空格,可以使用下划线(_)。

  • 不能使用标点符号。

  • 不能使用bash里的关键字(可用help命令查看保留关键字)。

  • 变量名不加美元符号 $

定义变量的时候,我们通常直接显式赋值!如
a=10b= "10"echo $aecho $b


变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界除了显式地直接赋值,还可以用语句给变量赋值,如:
for file in `ls /etc`或for file in $(ls /etc)
使用变量,想到大家已经猜到了 这里和php的做法一致: $变量名的形式取出来,但是有如下情况,我们向变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,例如:
a=5echo 我是第$a个程序员
解释器无法智能的理解变量名是 a,而去把变量名理解成了 a个程序员,这里少了什么?少了边界!如果我们使用{}括起来,完美解决了:echo 我是第${a}个程序员只读变量: 使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。例如:
a=10readonly aa=11#错误 zsh: read-only variable: a
删除变量 :unset ,变量被删除后不能再次使用。unset 命令不能删除只读变量。例如 unset a

环境变量

所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。使用env 命令就可以输出所有环境变量!bash有两个基本的系统级配置文件:/etc/bashrc和/etc/profile。这些配置文件包含了两组不同的变量:shell变量和环境变量。shell变量是局部的,而环境变量是全局的。环境变量是通过shell命令来设置。设置好的环境变量又可以被所以当前用户的程序使用。常用的环境变量如下:USER UID HOME PATH SHELL PS1 PS2 TMOUT这些都是大写命令组成,我们shell可以直接使用它,我们简单介绍一下 PS1 PS2 TMOUT
  • PS1第一级Shell命令提示符,root用户是#,普通用户是$
  • PS2第二级命令提示符,默认是“>” ,什么是 二级命令提示符 ? 我们是输入一大串命令的时候 ,可以使用 \连接符换到下一行输入,此时,bash的提示符就是二级提示符:
  • TMOUT用户和系统交互过程的超时值。系统与用户进行交互时,系统提示让用户进行输入,但用户迟迟没有输入,时间超过TMOUT设定的值后,shell将会因超时而终止执行。
  • PATH , 这里和windows上的 path是一致的,只要我们把可执行文件添加到PATH中去 ,我们输入文件名就可以执行对应的可执行文件。每一个冒号都是一个路径,这些搜索路径都是一些可以找到可执行程序的目录列表。当我们输入一个指令时,shell会先检查命令是否是内部命令,不是的话会再检查这个命令是否是一个应用程序。然后shell会试着从搜索路径,即PATH中寻找这些应用程序。如果shell在这些路径目录里没有找到可执行文件。则会报错。若找到,shell内部命令或应用程序将被分解为系统调用并传给Linux内核。那么我们如果添加 PATH呢?使用export指令,将a.out的路径添加到搜索路径当中,命令:export PATH=$PATH:路径 (PATH中路径是通过冒号“:”进行分隔的,把新的路径加在最后就OK)

位置变量 与 预定义变量

和bat脚本一样,也有位置变量,bat中读取%1 %2 %...可以读取执行命令传入的第一个参数和第二个参数 等,shell这里也是这样的,$1 $2 可以取出对应的变量。常用的预定义变量有很多 ,如 $ # * @ ? 0 ! 我们直接使用shell脚本展示一下
#! /bin/bashecho 位置变量和预定义变量echo 1:$1echo 2:$2echo '$':$$echo '#':$#echo *:$*echo @:$@echo ?:$?echo !:$!
部分预定义变量含义如下:
  1. # $#变量是命令行参数或位置参数的数量

  2. ?,$? 变量是最近一次执行的命令或shell脚本的出口状态,0表示成功 非零表示错误

  3. $ ,$$ 变量是shell脚本里面的进程ID。Shell脚本经常使用 $$ 变量组织临时文件名,确保文件名的唯一性。

  4. !,&! 变量的值是最近运行的一个后台进程的PID ,我们执行命令的时候使用 &,可以让程序后台执行,使用&!获取它的进程号

  5. * ,$* 变量的值表示所有的位置参数,其值是所有位置参数的值

  6. @,$@ 变量的值类似于$*,表示所有的位置参数,其值也是所有位置参数的值。

2.2三种引号

shell脚本有三种引号我们要注意
  1. “” 界定范围
  2. ‘’ 界定范围并且屏蔽特殊符号!

2.3全局变量和局部变量

我们通常使用 a=10 ,声明的是局部变量,只能在当前bash中使用,如果我们新开一个bash, a变量就未定义了!有局部就有全局,我们可以将一个定义完成的变量声明为全局变量 使用 export 变量名 ,也可以边定义边 声明为全局 export a=10 ,如果想取消它的全局身份,我们需要输入 export -n a 这样a转换成为局部变量了。

2.4回显控制

和C语言一样,我们需要scanf()类似功能。shell中我们常用 read 命令read可以带有-a, -d, -e, -n, -p, -r, -t, 和 -s八个选项。会使用 -p ,我感觉就够了
#! /bin/bashread -p "请输入变量 n" necho 输入变量为$n
当然如果我们输入的变量如果是命令是 密码等 这样 私密的数据,我们可以使用 stty -echo 屏蔽键盘输入bash的内容 却不屏蔽系统输出 ,再次输入stty echo就会恢复了。当然如果我们想把系统的回显也屏蔽呢?我们可以把 该命令的标准错误和 标准输出都重定向到 /dev/null中,如下ls &> /dev/null

2.5变量运算

expr

常有运算符 + - * / %,不必多言我们使用 expr命令来运算表达式并且输出:例如
#! /bin/bashecho + :expr 1 + 5echo / :expr 1 / 2echo \* :expr 5 \* 6echo % :expr 6 % 4echo 使用 echo '$[]'echo $[5*6]
使用 echo $[表达式] 也可以达到类似的效果,使用 epre ,值得注意的是 * 是特殊符号,需要转义

let

我们可以使用let 可以修改 变量的本身 并且不显示结果,例如 如果我们这样使用如果使用let ,如下:当然让我们也可使用 let a++ 来自增变量 -- += -= ... 等C语言出现过的一元赋值运算符都是一个道理。很可惜的是 shell脚本无法直接使用小数计算

使用bc 完成小数以及复杂的运算

我们可以使用bc命令以及 echo管道配合| 来计算小数例如:
#! /bin/bashecho "scale=3;10/3" | bc

2.6流程控制

shell条件表达式

一门编程语言常具这几种条件控制语句:
  1. if

  2. case

  3. for

  4. while

条件式我们需要 使用 [ ]包括起来,注意表达式与 []两侧有空格隔离,并且条件运算符之间也需要空格隔离 ,这是为了防止识别成一个变量,关系运算符有 (列举常用的)
  1. = 相等 ,常用字符类数据对比

  2. != 不相等 ,常用字符类数据对比

  3. -z 判断字符串长度是否为0

  4. -eq 等于,这个以及下面的常用于数值类型数据对比

  5. -ne 不等于

  6. -gt 大于

  7. -ge 大于等于

  8. -lt 小于

  9. -le 小于等于

  10. ! 取非

shell中还有争对文件和目录中进行判断的
  1. -e 判断文件或者目录是否存在

  2. -f 判断 是否为文件

  3. -d判断是否为目录

  4. -r 判断是否可读(root用户 无效)

  5. -w 判断是否可写(root用户 无效)

  6. -x 判断是否可执行

条件式不仅仅有关系运算符,还有逻辑运算符 && || 含义无需多少了, ,和C语言一样 这里也存在逻辑短路的特性!使用逻辑短路可以完成一些条件判断[ $USER != root ] || echo root如果我们要判断一个变量是否为空 我们需要这样操作: [ -Z "$变量" ] , -Z判断字串长度是否为0当然我们可以采用这样的书写方式 [[ -z $g ]] && echo 空, 规则如下:[ -z "$g" ] 单对中括号变量必须要加双引号[[ -z $g ]] 双对括号,变量不用加双引号.当然还有存在一个符号 ; 这里提一下 多个指令可以;隔开,; 可以看作没有逻辑功能的 运算符,可以利用它将多个命令写在一行内。

条件语句

if 单分支语句

虽然逻辑短路可以实现条件判断,但是可读性非常差,所以 条件语句我们一般都会使用 if语句,如果你是压缩代码狂,那么逻辑短路就非常适合你。if语法如下
# 语法一if 条件表达式 ; then  命令序列fi//表示if语句块结束#语法 2if 条件表达式 then  命令序列fi//表示if语句块结束#例如read -p "请输入用户名" uif [ -z $u ] ; then  echo "请输入用户名"  #...处理  exitfi
由于 shell没有像C语言用{}来标记语句块,shell的做法是 采用 fi 倒序的if来标记if语句的结束 。语法一和语法二 的区别不大,主要是是否使用 ; 来将命令放在一行

if多分支语句

语法如下:
# 双分支if 条件语句 ; then  #命令序列else  #命令序列if# 多分支if 条件语句 ; then  #命令序列elif 条件语句 ; then  #命令序列elif 条件语句 ; then  #命令语句#... else #命令序列fi

case语句

这个case语法和Pascal有点类似
case 值 in模式1)   命令序列     ;;模式2)  命令序列    ;;*)  默认情况;;esac
case 工作方式如上所示,取值后面必须为单词 in,每一模式必须以右括号结束。取值可以为变量或常数,匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;;。取值将检测匹配的每一个模式。一旦模式匹配,则执行完匹配模式相应命令后不再继续其他模式。如果无一匹配模式,使用星号 * 捕获该值,再执行后面的命令。

循环

和C语言一样,我们可以使用 break,continue 来进行循环控制,语法一致!

for 语句语法

for 变量名 in 值列表do  命令序列done #例如for i in {1..10}do  echo &idono for i in a b cdo#这样也会循环三次  echo abcdono#如果你想使用 变量来控制 循环测试 请使用 seq命令for i in `seq 10`do# 条件语句done  
seq命令可以输出连续的数字,或者输出固定间隔的数字,或者输出指定格式的数字。

while 语句

# 条件语句为真 循环while 条件语句do# 任务序列done# 另外一种形式 永远执行命令序列,无限循环while :do  #命令序列done

shell 函数

基础语法

我们可以使用 alias 来给一些命令起别名,比如 我们.bashrc中就定义着许多变量的别名,我们当然也可以手动更改。shell中的函数,我感觉理解成加强版的alias不错,函数是为了给一堆命令序列起别名,使用函数和使用命令的语法是一致的。例如:
#! /bin/bashfun(){    echo 函数的使用和命令一样    for i in $*    do        echo $i    done} fun c1 c2 c3

函数的传参和取返回值

函数是为了给一堆命令序列起别名,使用函数和使用命令的语法是一致的,所以传参使用 位置变量即可 ,取返回值使用 $? 取返回值。这里就说明了 返回值为啥是 0-255的原因了

练习 -- 检查当前网段有多少主机和主机ip

#! /bin/bashmyping(){    ping -c1 -W1 $1 &> /dev/null    [ $? -eq 0 ] && echo "$1 is open"}# 获取主机ipa=` ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d '/' `echo $ab=`echo ${a%.*}`echo "测试网段为 ${b}.x"#ping for i in `seq 254`do    myping ${b}.${i} &done wait
wait 命令的作用是等待所有的 后台程序结束后 才结束 wait配合 & 后台执行 相当于 C语言的fork语句更多教程 关注我们
注:本文转载自:https://blog.yxqin.top/2021/07/16/linuxshell(如有侵权 请联系我们删除)

原文作者:Kali笔记;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2021-01-22

  • 博文量
    760
  • 访问量
    444213