什么是程序
程序是为实现特定目标或解决特定问题而用计算机语言编写的命令序列的集合。简单来说,电脑里面的应用都是程序来控制的,程序天天见。程序是由序列组成的,告诉计算机如何完成一个具体的任务。由于现在的计算机还不能理解人类的自然语言,所以还不能用自然语言编写计算机程序,不过现在语音识别技术己经很历害了,在不久的将来,估计,电脑就自己会编程序了。
程序能做什么?
电脑控制手机控制机械控制物联,一切自动化制造的系统,都是由程序来控制的。
什么是编程?
编程是一个动词,编程==写代码。写代码为了什么?为了让计算机干你想要干的事情。
语言
那计算机能理解的语言是什么?
计算机只能理解二进制,如:01010101等。如果使用二进制来写代码,这样开发速度太慢。所以最好的办法就是人输入简单的指令,计算机能把指令转成二进制执行。
有哪些编程语言呢?
编程语言总体分为:机器语言、汇编语言、高级语言
机器语言
由于计算机内部只能接受二进制,因此用二进制代码0和1描述的指令成为机器指令,全部机器指令的集合构成计算机的机器语言。用机器语言编程的程序成为目标程序,只有目标程序才能被计算机直接识别和执行。但是机器语言编写的程序无明显特征,难以记忆,不便于阅读和书写,且依赖与具体机种,局限性很大,机器语言属于低级语言。
用机器语言编写程序,编程人员要首先熟记所用计算机的全部指令代码和代码的涵义。手编程序时,程序员得自己处理每条指令和每一数据的存储分配和输入输出,还得记住编程过程中每步所使用的工作单元处在何种状态。这是一件十分繁琐的工作。编写程序花费的时间往往是实际运行时间的几十倍或几百倍。而且,编出的程序全是些0和1的指令代码,直观性差,还容易出错。除了计算机生产厂家的专业人员外,绝大多数的程序员已经不再去学习机器语言了。
机器语言是微处理器理解和使用的,用于控制它的操作二进制代码。
汇编语言
汇编语言的实质和机器语言是相同的,都是直接对硬件操作,只不过指令采用了英文缩写的标识符,更容易识别和记忆。它同样需要编程者将每一步具体的操作用命令的形式写出来。
汇编程序的每一句指令只能对应实际操作过程中的一个很细微的动作。例如移动、自增,因此汇编源程序一般比较冗长、复杂、容易出错,而且使用汇编语言编程需要有更多的计算机专业知识,但汇编语言的优点也是显而易见的,用汇编语言所能完成的操作不是一般高级语言所能够实现的,而且源程序经汇编生成的可执行文件不仅比较小,而且执行速度很快。
高级语言
高级语言是大多数编程者的选择。和汇编语言相比,它不但将许多相关的机器指令合成为单条指令,并且去掉了与具体操作有关但与完成工作无关的细节,例如使用堆栈、寄存器等,这样就大大简化了程序中的指令。同时,由于省略了很多细节,编程者也就不需要有太多的专业知识。
高级语言主要是相对于汇编语言而言,它并不是特指某一种具体的语言,而是包括了很多编程语言,像最简单的编程语言PASCAL语言也属于高级语言。
高级语言所编制的程序不能直接被计算机识别,必须经过转换才能被执行,按转换方式可将它们分为两类:
编译类
编译是指在应用源程序执行之前,就将程序源代码“翻译”成目标代码(机器语言),因此其目标程序可以脱离其语言环境独立执行(编译后生成的可执行文件,是cpu可以理解的2进制的机器码组成的),使用比较方便、效率较高。但应用程序一旦需要修改,必须先修改源代码,再重新编译生成新的目标文件(*.obj,也就是OBJ文件)才能执行,只有目标文件而没有源代码,修改很不方便。
编译后程序运行时不需要重新翻译,直接使用编译的结果就行了。程序执行效率高,依赖编译器,跨平
台性差些。如C、C++、Delphi等。
解释类
执行方式类似于我们日常生活中的“同声翻译”,应用程序源代码一边由相应语言的解释器“翻译”成目标代码(机器语言),一边执行,因此效率比较低,而且不能生成可独立执行的可执行文件,应用程序不能脱离其解释器(想运行,必须先装上解释器,就像跟老外说话,必须有翻译在场),但这种方式比较灵活,可以动态地调整、修改应用程序。如Shell,Python、Java、PHP、Ruby等语言。
总结
机器语言
- 优点:最底层,速度最快
- 缺点:最复杂,开发效率最低
汇编语言
- 优点:较为底层,速度较快
- 缺点:较为复杂,开发效率较低
高级语言
- 编译型:执行速度快,但跨平台性差
- 解释型:跨平台性强,但执行速度慢
Shell概述
什么是Shell?
首先Shell的英文含义是“壳”; 它是相对于内核来说的,因为它是建立在内核的基础上,面向于用户的一种表现形式,比如我们看到一个球,见到的是它的壳,而非核。 Linux中的Shell,是指一个面向用户的命令接口,表现形式就是一个可以由用户录入的界面,这个界面也可以反馈运行信息;
Shell在Linux中的存在形式
由于Linux不同于Windows,Linux是内核与界面分离的,它可以脱离图形界面而单独运行,同样也可以在内核的基础上运行图形化的桌面。 这样,在Linux系统中,就出现了两种Shell表现形式,一种是在无图形界面下的终端运行环境下的Shell,另一种是桌面上运行的类似Windows 的MS-DOS运行窗口,前者我们一般习惯性地简称为终端,后者一般直接称为Shell。
Shell如何执行用户的指令
Shell有两种执行指令的方式:
- 第一种方法是用户事先编写一个sh脚本文件,内含Shell脚本,而后使用Shell程序执行该脚本,这种方式,我们习惯称为Shell编程。
- 第二种形式,则是用户直接在Shell界面上执行Shell命令,由于Shell界面的关系,大家都习惯一行行的书写,很少写出成套的程序来一起执行,所以也称命令行。
总结
Shell 只是为用户与机器之间搭建成的一个桥梁,让我们能够通过Shell来对计算机进行操作和交互,从而达到让计算机为我们服务的目的。
Shell的分类
Linux中默认的Shell是/bin/bash,流行的Shell有ash、bash、ksh、csh、zsh等,不同的Shell都有自己的特点以及用途。
bash
大多数Linux系统默认使用的Shell,bash Shell是Bourne Shell 的一个免费版本,它是最早的Unix Shell。
bash还有一个特点,可以通过help命令来查看帮助。包含的功能几乎可以涵盖Shell所具有的功能,所以一般的Shell脚本都会指定它为执行路径。
csh
C Shell 使用的是“类C”语法,csh是具有C语言风格的一种Shell,其内部命令有52个,较为庞大。目前使用的并不多,已经被/bin/tcsh所取代。
tcsh
tcsh是csh的增强版,与C Shell完全兼容。
ksh
Korn Shell 的语法与Bourne Shell相同,同时具备了C Shell的易用特点。许多安装脚本都使用ksh,ksh 有42条内部命令,与bash相比有一定的限制性。
sh
是一个快捷方式,已经被/bin/bash所取代。
zsh
目前Linux里最庞大的一种 zsh。它有84个内部命令,使用起来也比较复杂。一般情况下,不会使用该Shell。
Shell能做什么?
- 自动化批量系统初始化程序 (update,软件安装,时区设置,安全策略...)
- 自动化批量软件部署程序(LAMP,LNMP,Tomcat,LVS,Nginx)
- 应用管理程序(KVM,集群管理扩容,MySQL,DELLR720批量RAID)
- 日至分析处理程序(PV, UV, 200, !200, top 100, grep/awk)
- 自动化备份恢复程序(MySQL完全备份/增量 + Crond)
- 自动化管理程序(批量远程修改密码,软件升级,配置更新)
- 自动化信息采集及监控程序(收集系统/应用状态信息,CPU,Mem,Disk,Net,TCP Status,Apache,MySQL)
- 配合Zabbix信息采集(收集系统/应用状态信息,CPU,Mem,Disk,Net,TCP Status,Apache,MySQL)
- 自动花扩容(增加云主机——>业务上线)
- Zabbix监控CPU 80%+|-50% Python API AWS/EC2(增加/删除云主机) + Shell Script(业务上线)
login shell与nologin shell的区别
表面区别
Login shell就是你进入shell是需要输使用者名称密码的,比如你启动图形介面最后一步需要你输入使用者名称密码,只有你输入正确,才能进入桌面,这进入的就是一个login shell 。另外比如你ctrl + alt + F2等进入非图形介面的tty ,都是需要你输入使用者名称密码之后才能继续操作,这种情况下你进入的就是login shell 。
而nologin shell就是你不需要输入密码就能进入的shell 。比如你进入图形介面之后,右键开启终端,就直接打开了一个承载shell的终端,在这个终端中你不用输入使用者名称密码就直接可以使用命令。
这只是表面上的区别,其实真正影响这两种shell使之不同的是开启两者所读取的环境变数档案不同。
深层区别
区分login shell和no login shell的主要原因是它们启动和退出时自动执行的脚本不同。
login shell
对于login shell其启动时自动执行的脚本文件顺序如下
- 首先执行
/etc/profile
- 再执行
~/.bash_profile
,~/.bash_login
,~/.profile
中第一个存在的脚本(按顺序搜索,只会执行其中一个)
如果shell启动时添加了--noprofile
选项则不会执行上述文件。在login shell退出时,会执行~/.bash_logout
no login shell
对于no login shell,启动时会执行/etc/bashrc
和~/.bashrc
,如果shell启动时添加了--norc
选项则不会执行上述文件,如果添加了--rcfile
选项则会执行指定的filename文件,也不会执行上述文件。no login shell退出时不会自动执行脚本文件。
而我们知道nologin shell一定是在已经登入了login shell的前提下开启的,比如字元视窗startx启动图形介面,或者图形介面里开启新的终端。所以nologin shell算是login shell的一个子程式,根据shell中变数的继承法则,nologin shell会在继承原本login shell所有的环境变数的基础上读取~/.bashrc中的引数。
这就是这些个档案所有的关系了。所以有的时候,你设定的环境变数并没有生效,可以根据这个读取顺序检视一下是不是你的设定被覆盖掉了……
总结
no login shell和login shell在启动和退出时会执行不同的脚本文件从而影响shell中的环境变量,本文根据bash的文档描述了两种shell启动时自动执行的脚本文件的区别。
login shell和no login shell启动时执行的脚本文件是完全不同的,因此,运行环境初始化脚本需要合理配置才能让login shell和no login shell都能执行,同时也可以为login shell和no login shell配置不同的运行环境初始化脚本。
- 根据该定义,我们可以使用
bash --login
启动一个login shell或者通过echo $0
的输出结果是否以/
开头来判断一个shell是否为login shell。
bash初识化
bash环境变量文件
/etc/profile
:全局(公有)配置,不管是哪个用户,登录时都会读取该文件。/etc/bashrc
:它也是全局(公有)的,bash 执行时,不管是何种方式,都会读取此文件。(Ubuntu 没有此文件,与之对应的是 /ect/bash.bashrc)~/.bash_profile
、~/.bash_login
、~/.profile
:若 bash 是以 login 方式执行时,读取~/.bash_profile
,若它不存在,则读取~/.bash_login
,若前两者都不存在,读取~/.profile
。~/.bashrc
:当 bash 是以 non-login 形式执行时,读取此文件。若是以 login 形式执行,则不会读取此文件。~/.bash_logout
:当为login形式注销时,此文件才会被读取。
bash环境变量文件加载顺序
- 图形模式登录时,顺序读取:
/etc/profile
和~/.profile
- 图形模式登录后,打开终端时,顺序读取:
/etc/bashrc
和~/.bashrc
- 文本模式登录时,顺序读取:
/etc/bashrc
,/etc/profile
和~/.bash_profile
从其它用户 su 到该用户,则分两种情况:
- 如果带 -l 参数(或-参数,--login 参数),如:
su -l username
,则 bash 是 login 的,它将顺序读取以
下配置文件:/etc/bashrc
,/etc/profile
和~/.bash_profile
。 - 如果没有带 -l 参数,则 bash 是
non-login
的,它将顺序读取:/etc/bashrc
和~/.bashrc
- 如果带 -l 参数(或-参数,--login 参数),如:
注销时,或退出 su 登录的用户,如果是 longin 方式,那么 bash 会读取:
~/.bash_logout
。- 执行自定义的 Shell 文件时,若使用
bash -l a.sh
的方式,则 bash 会读取:/etc/profile
和~/.bash_profile
。若使用其它方式,如:bash a.sh
,./a.sh
,sh a.sh
(这个不属于bash Shell),则不
会读取上面的任何文件。 - 上面的例子凡是读取到
~/.bash_profile
的,若该文件不存在,则读取~/.bash_login
,若前两者不存
在,读取~/.profil
。
- 执行自定义的 Shell 文件时,若使用
bash特征
命令历史记忆功能
Bash 有自动记录命令的功能,自动记录到.bash_history
隐藏文件中。在bash中,使用history 命令来查看和操作之前的命令,以此来提高工作效率。
# 查看之前使用的所有命令
$ history
# 显示最近的n个命令
$ history n
# 删除相应的第n个命令
$ history -d n
# 指定执行命令历史中的第n条语句
$ !n
# 指定执行命令历史中倒数第n条语句
$ !-n
# 执行命令历史中最后一条语句
$ !!
# 执行命令历史中最近一条以[String]开头的语句(不需要写[])
$ ![String]
# 引用上一个命令中的最后一个参数
$ !$
# 将命令历史写入命令历史文件中
$ history -w
# 回显 echo 之后的语句,而使用 echo $FILENAME 命令可以查看该 file 所在的路径
$ echo $HISTFILE
# 查看命令历史的内容
$ cat .bash_history
# 删除所有的命令历史记录
$ history -c
别名功能
alias
命令可以为其他命令起别名,这样可以把本来很成长的指令简化缩写,来提高工作效率。
# 查看系统当前所有的别名
$ alias
# 定义新的别名
$ alias newName='oldName'
# 删除已定义的别名
$ unalias newName
如果想要文件永久生效,只需将上述别名命令写到对应用户或者系统.bashrc
文件中,然后source
一下.bashrc
文件。如果想用真是命令可以在命令前面添加反斜杠,使别名失效。
快捷键
快捷键 | 作用 |
---|---|
ctrl + A | 把光标移动到命令行开头。 |
ctrl + E | 把光标移动到命令行结尾。 |
ctrl + C | 强制终止当前的命令。 |
ctrl + L | 清屏,相当于clear命令。 |
ctrl + U | 删除或剪切光标之前的命令。 |
ctrl + K | 删除或剪切光标之后的内容。 |
ctrl + Y | 粘贴ctrl+U或ctrl+K剪切的内容. |
ctrl + R | 搜索历史记录。 |
ctrl + D | 退出当前终端。 |
ctrl + Z | 暂停,并放入后台。 |
ctrl + S | 暂停屏幕输出。 |
ctrl + Q | 恢复屏幕输出。 |
前后台作业控制
Linux bash Shell单一终端界面下,经常需要管理或同时完成多个作业,如一边执行编译,一边实现数据备份,以及执行SQL查询等其他的任务。所有的上述的这些工作可以在一个 bash 内实现,在同一个终端窗口完成。
前后台作业的定义
前后台作业实际上对应的也就是前后台进程,因此也就有对应的 pid。在这里统称为作业。
无论是前台作业还是后台作业,两者都来自当前的Shell,都是当前Shell的子程序。
- 前台作业:可以由用户参与交互及控制的作业。
- 后台作业:在内存可以自运行的作业,用户无法参与交互以及使用[ctrl]+c来终止,只能通过bg或fg来调用的作业。
几个常用的作业命令
command &
:直接在命令的后面加上&,即可让执行的命令作业进入后台运行。ctrl + z
:使用这个组合快捷键也可以让当前作业切换到后台运行。jobs
:使用此命令可以查看后台作业状态。fg %n
:n为编号,使用此命令可以让后台运行的作业n切换到前台运行。bg %n
:n为编号,使用此命令可以让前台运行的作业n切换到后台运行。kill -9 %n
:强制终止执行的作业n。kill -15 %n
:正常终止执行的作业n。
作业脱机管理
将作业(进程)切换到后台可以避免由于误操作如[ctrl]+c等导致的job被异常中断的情形,而脱机管理主要是针对终端异常断开的情形。
通常使用nohup命令来使得脱机或注销之后,Job依旧可以继续运行。也就是说nohup忽略所有挂断(SIGHUP)
信号。
如果该方式命令之后未指定&符号,则job位于前台,指定&符号,则job位于后台。