信息安全系统设计与实现:第十章学习笔记
20191331 lyx
教材学习内容总结
第十章 sh编程
本章主要学习目标
本章介绍了sh脚本,sh脚本与C语言的区别,如何编写sh脚本:变量、语句、命令、常规系统命令和命令替换,解释了sh控制语句和他们的使用方法,说明了如何编写sh函数以及使用参数调用函数。
总结一下一门程序设计语言有哪些必备的要素和技能?这些要素和技能在shell脚本中是如果呈现出来的?
现在的编程语言种类繁多,每个语言都有其各自的特点,我们可以根据自己的喜好来选择一门编程语言,可以根据某个编程语言的特点来针对性学习,但无论学习哪种语言,一个强有力的语言都要提供下面三种机制,使我们能够在其中组织自己有关计算过程的思想:
- 基本表达形式,用于描述和形容要操作的对象。
- 组合的方法,通过它们可以从简单的东西出发构造出复合的元素。
- 抽象的方法,通过它们可以为复合对象命名,并将它们当作单元去操作。
编程语言能够组织以下形式:
- 数据类型和变量
- 运算符和表达式
- 控制流(条件判断和循环)
- 函数
在shell中,我们就可以定义合适的变量,通过选择、循环、函数的调用来完成各种各样的功能,来达到自动化控制的目的,以减少重复相同操作浪费的时间。
什么是sh
shell是外壳的意思,就是操作系统的外壳。
我们可以通过shell命令来操作和控制操作系统,比如Linux中的Shell命令就包括ls、cd、pwd等等。总结来说,Shell是一个命令解释器,它通过接受用户输入的Shell命令来启动、暂停、停止程序的运行或对计算机进行控制。
什么是脚本
脚本就是由Shell命令组成的文件,这些命令都是可执行程序的名字,脚本不用编译即可运行。脚本本身就相当于一个可执行文件。
它通过解释器解释运行,所以速度相对来说比较慢。
sh脚本和c语言
-
sh脚本是解释程序,它会逐行读取sh脚本并直接执行,而C语言恰恰相反,它必须先编译链接,然后通过主sh的子进程运行二进制可执行文件。
-
在C程序中,每个变量必须有一个类型,例如char、int、float、派生类型(如 struct)等。相反,在 sh脚本中,每个变量都是字符串。
-
每个c程序必须有一个main()函数,每个函数必须定义一个返回值类型和参数(如有)。相反,sh脚本不需要main函数。在 sh脚本中,第一个可执行语句是程序的入口点。
linux中的脚本解释器
以我的环境为例 OpenEuler 20.03 LTS
内置的脚本解释器为bash
sh的命令参数
$0 表示程序名。
$1 至 $9则是位置参数。
$# 表示参数的个数。
$* 将所有参数当做一个整体来引用
$@ 把每个参数作为一个字符串返回,可以使用for循环来遍历
$? 最近一个执行的命令的退出状态。0表示执行成功
$_ 上一个命令的最后一个参数。使用快捷键 ESC+. 也是这个效果
位置参数
位置参数不止9个,更多的参数也是一样支持的。只是要使用${10}这样的形式引用。
$1 和 ${1}的效果是一样的。
不用花括号的话,$10 会被认为是 $1 和一个字符 0。
Shell 变量的命名规范
- 变量名由数字、字母、下划线组成;
- 必须以字母或者下划线开头;
- 不能使用 Shell 里的关键字(通过 help 命令可以查看保留关键字)。
sh 命令 和 linux 命令
书p238
命令 | 说明 |
---|---|
alias | 为指定命令定义一个别名 |
bg | 将作业以后台模式运行 |
bind | 将键盘序列绑定到一个 readline 函数或宏 |
break | 退出 for、while、select 或 until 循环 |
builtin | 执行指定的 shell 内建命令 |
caller | 返回活动子函数调用的上下文 |
cd | 将当前目录切换为指定的目录 |
command | 执行指定的命令,无需进行通常的 shell 查找 |
compgen | 为指定单词生成可能的补全匹配 |
complete | 显示指定的单词是如何补全的 |
compopt | 修改指定单词的补全选项 |
sh可以执行所有的linux命令。
管道命令作为过滤器
ps -ef | grep xxx
命令替换
Shell 命令替换是指将命令的输出结果赋值给某个变量。
variable=$(commands)
sh控制语句 与 实践练习
- if-else-fi
read a
read b
if (( $a == $b ))
then
echo "a和b相等"
fi
- for语句
sum=0
for ((i=1; i<=100; i++))
do
((sum += i))
done
echo "The sum is: $sum"
- while语句
i=1
sum=0
while ((i <= 100))
do
((sum += i))
((i++))
done
echo "The sum is: $sum"
- until-do语句
i=1
sum=0
until ((i > 100))
do
((sum += i))
((i++))
done
echo "The sum is: $sum"
- case语句
printf "Input integer number: "
read num
case $num in
1)
echo "Monday"
;;
2)
echo "Tuesday"
;;
3)
echo "Wednesday"
;;
4)
echo "Thursday"
;;
5)
echo "Friday"
;;
6)
echo "Saturday"
;;
7)
echo "Sunday"
;;
*)
echo "error"
esac
通配符
file *:列出当前目录中所有文件的信息
ls *.c:列出当前目录中所有以.c结尾的文件
file ???:有3个字符的所有文件名
ls *.???:一个点号,后有两个字符的所有文件名
[]:查询文件名中一对[]中的字符
I/O重定向
当进入sh命令时,我们可以指示sh将I/O重定向到除默认stdin、stdout和sterr以外的文件。
sh脚本调试
Shell本身提供一些调试方法选项:
- -n,读一遍脚本中的命令但不执行,用于检查脚本中的语法错误。
- -v,一边执行脚本,一边将执行过的脚本命令打印到标准输出。
- -x,提供跟踪执行信息,将执行的每一条命令和结果依次打印出来。
1.在命令行提供参数:$sh -x script.sh
2.脚本开头提供参数:#!/bin/sh -x
3.在脚本中用set命令启用or禁用参数:其中set -x
表示启用,set +x
表示禁用。
使用这些选项有三种方法(注意:避免几种调试选项混用)
sh脚本实践
通过sh脚本来打印梯形并使用调试参数
#!/bin/bash
read -p "输入数" p
for ((i=1;i<=$p;i++))
do
for ((o=$i;o<$p;o++))
do
echo -n " "
done
for ((j=$i+1;j>=0;j--))
do
echo -n "* "
done
echo ""
done
利用sh脚本自动创建sh格式化项目
指定创建目录,脚本名称,附带时间戳,简化sh脚本的创建过程。
编写一个脚本来帮我们更加快捷的编写脚本。
#!/bin/bash
if [[ -z "$1" ]];then
newfile=~/newscript_`date +%m%d_%S`
else
newfile=$1
fi
if ! grep "^#!" $newfile &>/dev/null; then
cat >> $newfile << EOF
#!/bin/bash
# Author: Inert Your Name here.
#Date & Time: `date +"%F %T"`
#Description: Please Edit here.
EOF
fi
vim +5 $newfile
根据PID过滤进程所有信息
read -p "请输入要查询的PID: " P
n=`ps -aux| awk '$2~/^'$P'$/{print $11}'|wc -l`
if [ $n -eq 0 ];then
echo "该PID不存在!!"
exit
fi
echo "--------------------------------"
echo "进程PID: $P"
echo "进程命令:`ps -aux| awk '$2~/^'$P'$/{print $11}'`"
echo "进程所属用户: `ps -aux| awk '$2~/^'$P'$/{print $1}'`"
echo "CPU占用率:`ps -aux| awk '$2~/^'$P'$/{print $3}'`%"
echo "内存占用率:`ps -aux| awk '$2~/^'$P'$/{print $4}'`%"
echo "进程开始运行的时刻:`ps -aux| awk '$2~/^'$P'$/{print $9}'`"
echo "进程运行的时间:`ps -aux| awk '$2~/^'$P'$/{print $10}'`"
echo "进程状态:`ps -aux| awk '$2~/^'$P'$/{print $8}'`"
echo "进程虚拟内存:`ps -aux| awk '$2~/^'$P'$/{print $5}'`"
echo "进程共享内存:`ps -aux| awk '$2~/^'$P'$/{print $6}'`"
echo "--------------------------------"
其他脚本语言实践
原因:Mars是java开发的一款软件,不知道是什么原因,我win10系统下双击无反应,但可以从命令行进入,于是我就想通过编写一个脚本来提高我的使用体验。
脚本名:start_Mars.vbs
脚本内容:
Set Ws = CreateObject("Wscript.Shell")
Ws.Run("java -jar F:Mars4_5.jar"),0
简单却很高效
感悟
脚本可以极大的将我们从一些繁重但重复的无意义劳动中解放出来,它可以很方便的快速处理大规模相同数据。我希望能通过脚本语言的学习,让自己在今后的学习和生活中更加便利。
参考资料
脚本调试:https://www.cnblogs.com/anliven/p/6032081.html
sh内部命令:https://www.html.cn/script/44989.html#:~:text=常用的内部命令有,ft、exit。
shell编程:http://c.biancheng.net/view/1164.html
20191331lyx
2021/9/25