20201317-第10章学习笔记
第十章 shell编程
程序设计语言必备的要素和技能
程序设计语言的含义
程序设计语言是用于书写计算机程序的语言。
语言的基础是一组记号和一组规则。
根据规则由记号构成的记号串的总体就是语言。在程序设计语言中,这些记号串就是程序。
程序设计语言有3个方面的因素,即语法、语义和语用。语法表示程序的结构或形式,亦即表示构成语言的各个记号之间的组合规律,但不涉及这些记号的特定含义,也不涉及使用者。语义表示程序的含义,亦即表示按照各种方法所表示的各个记号的特定含义,但不涉及使用者。
程序设计语言特性
程序设计语言具有心理工程及技术等特性。
-
心理特性:歧义性、简洁性、局部性、顺序性、传统性。
-
工程特性:可移植性,开发工具的可利用性,软件的可重用性、可维护性。
-
技术特性:支持结构化构造的语言有利于减少程序环路的复杂性,使程序易测试、易维护。
shell是个脚本语言,也是应用程序与内核进行交互的桥梁(一个让开发者与内核交互的软件)。 比如我们计算机的运行状态等我们是无法肉眼来查看的,但是通过shell我们就能看到他的数据,其他一些应用程序,比如浏览器、音乐播放器等获得内核所掌管的音频、显卡等驱动的帮助。 shell也是个脚本语言,我们可以将一系列的操作放入一个文件中,并给予这个文件可执行的权限,我们就可以一下运行文件中的所有的指令,比如我们有一系列的操作经常使用,但是一个一个的打是在太麻烦了,我们可以将他写到一个脚本中,只需一次运行所有的操作就完成了。 而C语言是另一种高级的计算机语言,他可以开发很多软件,其实shell也是用c写的。
优点
快速开发:脚本语言极大地简化了“开发、部署、测试和调试”的周期过程。
容易部署:大多数脚本语言都能够随时部署,而不需要耗时的编译/打包过程。
同已有技术的集成:脚本语言被Java或者COM这样的组件技术所包围,因此能够有效地利用代码。
易学易用:很多脚本语言的技术要求通常要低一些,因此能够更容易地找到大量合适的技术人员。
动态代码:脚本语言的代码能够被实时生成和执行,这是一项高级特性,在某些应用程序里(例如JavaScript里的动态类型)是很有用也是必需的。[7]
缺点
脚本语言不够全面:它们会要求一门“真正的”编程语言的存在,必须找一个数据库驱动程序将其内置进脚本语言里。
脚本语言并不是软件工程和构建代码结构的最佳选择,例如面向对象和基于组件的开发。
脚本语言通常不是“通用”语言,但是能够根据专门的应用来调整,例如:PHP和万维网。[7]
什么是shell?
Shell 是一个命令解释器,它在操作系统的最外层,负责直接与用户进行对话,把用户的输入解释给操作系统,并处理各种各样的操作系统的输出结果,输出到屏幕反馈给用户。这种对话方式可以是交互式,也可以是非交互式的。
我们所输入的命令计算机是不识别的,这时就需要一种程序来帮助我们进行翻译,变成计算机能识
别的二进制程序,同时又把计算机生成的结果返回给我们。
简单来说,就是用户可以通过某种应用程序,来指挥内核,让程序来指挥内核,达成我们所需要的硬件任务。
广义shell: 能够操作应用程序的接口,包括图形界面的软件
狭义shell: 命令行方面的软件,包括bash。
当前终端使用的哪种 shell?
大多数 linux 发行版本默认 shell 使用的是 bash
什么是sh?
sh 的全称是 Bourne shell,由 AT&T 公司的 Steve Bourne开发,为了纪念他,就用他的名字命名了。
sh 是 UNIX 上的标准 shell,很多 UNIX 版本都配有 sh。sh 是第一个流行的 Shell。
sh 跟bash的区别,实际上是bash有没开启POSIX模式的区别。
什么是bash?
Bash,[Unix shell](https://baike.baidu.com/item/Unix shell?fromModule=lemma_inlink)的一种,在1987年由布莱恩·福克斯为了GNU计划而编写。1989年发布第一个正式版本,原先是计划用在GNU操作系统上,但能运行于大多数类Unix系统的操作系统之上,包括Linux与Mac OS X v10.4都将它作为默认shell。
Bash是[Bourne shell](https://baike.baidu.com/item/Bourne shell?fromModule=lemma_inlink)的后继兼容版本与开放源代码版本,它的名称来自[Bourne shell](https://baike.baidu.com/item/Bourne shell?fromModule=lemma_inlink)(sh)的一个双关语(Bourne again / born again):Bourne-Again SHell。
Bash是一个命令处理器,通常运行于文本窗口中,并能执行用户直接输入的命令。Bash还能从文件中读取命令,这样的文件称为脚本。和其他Unix shell 一样,它支持文件名替换(通配符匹配)、管道、here文档、命令替换、变量,以及条件判断和循环遍历的结构控制语句。包括关键字、语法在内的基本特性全部是从sh借鉴过来的。其他特性,例如历史命令,是从csh和ksh借鉴而来。总的来说,Bash虽然是一个满足POSIX规范的shell,但有很多扩展。
优点:
命令记忆能力,存在./bash_history中
命令与文件补全功能,tab进行文件、命令补全
文件命名设置功能
作业控制、前台、后台控制
程序脚本
linux中的shellscript,将平时管理系统常需要执行的连续命令写成一个文件,该文件并且可以通过交互的方式进行主机的检测工作;也可以通过shell提供的环境变量和相关命令进行设计。
认识和学习bash
bash shell的内置命令:type
明确命令来自于外部命令还是内置在bash中
type命令 用来显示指定命令的类型,判断给出的指令是内部指令还是外部指令。
命令类型:
- alias:别名。
- keyword:关键字,Shell保留字。
- function:函数,Shell函数。
- builtin:内建命令,Shell内建命令。
- file:文件,磁盘文件,外部命令。
- unfound:没有找到。
语法
type(选项)(参数)
选项
-t:输出“file”、“alias”或者“builtin”,分别表示给定的指令为“外部指令”、“命令别名”或者“内部指令”;
-p:如果给出的指令为外部指令,则显示其绝对路径;
-a:在环境变量“PATH”指定的路径中,显示给定指令的信息,包括命令别名。
命令的执行
命令行太长,我们在最后回车前添加\,不要加空格,进行转义,然后可以在第二行继续编写shell
成功转义后,会在下一行出现>
shell的变量功能
linux是多用户、多任务的环境,每个人的登录系统都可以取得一个bash,每个人都可以利用bash执行mail这个命令进行收取邮件,问题是bash如何得知你的邮件是哪个文件
这就需要“变量”的帮助
什么是变量?
通俗:让某一个特定字符串代表不固定的内容
- 可变性、方便性
- 影响bash环境操作的变量
- shell script的好帮手
变量显示与设置
显示:echo
变量的设置规则:
- 变量与内容之间用=号链接
- 等号两边不能直接接空格字符
- 只能是英文和数字,不能是数字开头
- 变量内容有空格,可以用双引号,或者单引号,将内容结合起来
- 可以用转义符,将特殊符号变成一般符号
- 通常大写字符表示环境变量。
- 取消变量的方式,就是unset+变量名称
- 自设变量在系统关闭后,进行了删除、清零进行删除
子进程
就是说,我们目前的shell情况下,去打开另一个新的shell
新的shell就是子进程
一般情况下,父进程的自定义变量是无法在子进程中使用
但是将父变量变成环境变量后,才可以在子进程中使用
history查看历史记录
shell script
Shell 中文意思贝壳,寓意类似内核的壳。Shell是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。
Shell 脚本(shell script)是一种为 shell 编写的脚本程序。常说的shell通常都是指 shell 脚本,但shell和shell script是两个不同的概念。通常说“shell编程”都是指 shell 脚本编程,不是指开发 shell 自身。
为什么学习shell script?
- 自动化管理里
- 追踪和管理系统
- 简单入侵检测
- 连续命令单一化
- 简单的数据处理
- 跨平台支持与易学习
shell script的执行准则
- 命令的执行,是从上而下,从左而右的分析和执行
- 命令、参数间多个空白,会忽略掉
- 空白行被忽略,tab键所获得的空白也不会被执行
- 读取到一个ENTER符号,就开始执行,该行或者该串
- 一行内容太多,可以使用/Enter扩展至下一行
-
作为备注
简单的shell 脚本练习
1.交互式脚本--变量内容由用户决定
read -p "Please input your firstname:" firstname
read -p "Please input your lastname:" lastname
echo -e "\nYour full name is:$firstname $lastname"
随日期变化:利用日期进行文件的创建
我的服务器有数据库,数据库每天的数据都不太一样,备份时希望每一天备份一次数据
#1.user input name
echo -e "I will use 'touch' command to create 3 files."
read -p "please input your filename:" fileuser
#2.为了避免用户随意按[Enter],利用变量功能分析文件名是否有设置
filename=${fileuser:-"filename"} #开始判断是否有配置文件
#如果输入fileuser的有值的话,将该值付给filename
#3.开始利用date命令来取得所需要的文件名
date1=$(date --date='2 days ago' +%Y%m%d)
date2=$(date --date='1 days ago')
date3=$(date +%Y%m%d)
file1=${filename}${date1}
file2=${filename}${date2}
file3=${filename}${date3}
#4.创建文件名
touch "$file1"
touch "$file2"
touch "$file3"
数值运算
echo -e "Your SHOULD input 2 numbers, I will cross them \n"
read -p "first number:" firstsnu
read -p "second number:" secnu
total=$((firstsnu*secnu))
echo -e "\nThe reasult of $firstsnu x $secnu is ==> $total"
gcc调试方法
#include<stdio.h>
int main()
{
int s=0,a,n,t;
printf("请输入 a 和 n:\n");
scanf("%d%d",&a,&n);
t=a;
while(n>0)
{
s+=t;
a=a*10;
t+=a;
n--;
}
printf("a+aa+...=%d\n",s);
return 0;
}
gcc -g
产生编译信息
[root@bogon demo]# ls
main.c
[root@bogon demo]# gcc main.c -o main.exe
[root@bogon demo]# ls
main.c main.exe
可以看到,这里已经生成了 main.c 对应的执行文件 main.exe,但值得一提的是,此文件不支持使用 GDB 进行调试。原因很简单,使用 GDB 调试某个可执行文件,该文件中必须包含必要的调试信息(比如各行代码所在的行号、包含程序中所有变量名称的列表(又称为符号表)等),而上面生成的 main.exe 则没有。
gcc testgdb.c -o test.out -g
就可以执行进行调试了。
启动gdb
┌──(magic㉿DESKTOP-B4LCFDJ)-[~/helloc]
└─$ gdb test.out
GNU gdb (Debian 12.1-3) 12.1
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from test.out...
(gdb)
可以使用gdb -q来省略免责条款
调试指令 | 作 用 |
---|---|
(gdb) break xxx (gdb) b xxx | 在源代码指定的某一行设置断点,其中 xxx 用于指定具体打断点的位置。 |
(gdb) run (gdb) r | 执行被调试的程序,其会自动在第一个断点处暂停执行。 |
(gdb) continue (gdb) c | 当程序在某一断点处停止运行后,使用该指令可以继续执行,直至遇到下一个断点或者程序结束。 |
(gdb) next (gdb) n | 令程序一行代码一行代码的执行。 |
(gdb) print xxx (gdb) p xxx | 打印指定变量的值,其中 xxx 指的就是某一变量名。 |
(gdb) list (gdb) l | 显示源程序代码的内容,包括各行代码所在的行号。 |
(gdb) quit (gdb) q | 终止调试。 |
┌──(magic㉿DESKTOP-B4LCFDJ)-[~/helloc]
└─$ gdb test.out -q
Reading symbols from test.out...
(gdb) run
Starting program: /home/magic/helloc/test.out
warning: opening /proc/PID/mem file for lwp 128.128 failed: No such file or directory (2)
Failed to read a valid object file image from memory.
请输入 a 和 n:
12 34
a+aa+...=159072816
[Inferior 1 (process 128) exited normally]
(gdb) break 2
Breakpoint 1 at 0x8001161: file testgdb.c, line 4.
(gdb) run
Starting program: /home/magic/helloc/test.out
warning: opening /proc/PID/mem file for lwp 131.131 failed: No such file or directory (2)
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x8001159
(gdb)┌──(magic㉿DESKTOP-B4LCFDJ)-[~/helloc]
└─$ gdb test.out -q
Reading symbols from test.out...
(gdb) run
Starting program: /home/magic/helloc/test.out
warning: opening /proc/PID/mem file for lwp 128.128 failed: No such file or directory (2)
Failed to read a valid object file image from memory.
请输入 a 和 n:
12 34
a+aa+...=159072816
[Inferior 1 (process 128) exited normally]
(gdb) break 2
Breakpoint 1 at 0x8001161: file testgdb.c, line 4.
(gdb) run
Starting program: /home/magic/helloc/test.out
warning: opening /proc/PID/mem file for lwp 131.131 failed: No such file or directory (2)
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x8001159
(gdb)
遇到的问题
-
linux系统上,如何进行gdb调试?
答:因为拜托了Clion,Dev C++的集成开发环境,而出现了更直接的linux系统上,我对C的编写代码有些不适应,尤其是如何编译的问题上,经过老师的讲解,还有网上的资料,我顺利解决了问题。
-
什么是shell,如何理解shell脚本?
答:经过参考书籍,《鸟哥的linux》私房菜,我最后明白了shell脚本的具体意义。
-
shell脚本的运行出错的问题
答:主要是因为shell脚本运行时会出现shell空格问题,之前没有意识到空格也会对shell运行造成影响。
反思与总结
总的来说,本次学习我的收获很大。
首先,我学习到了我一直想学习的shell脚本,知道了shell是什么、怎么写
其次,我理解了我一直理解不透的gcc,gdb的运行机制
最后,是对我linux C、shell的底层设计,管理有了非常多的理解。