一.shell 概述
1.shell,用户敲命令的界面就是shell
外层应用程序如ls命令,会被shell翻译成机器语言然后传递给内核,然后内核传给硬件执行,硬件将运算结果传回给内核,shell将机器语言翻译成为可以被人看懂的运行结果。
windows的图形操作界面就相当于shell。
shell的作用? (1).命令解释器(2).做编程语言界面
2.分类
3.
输入 vim /etc/shells 可以看见LINUX支持的几种shell
直接输入shell的类型就能进行类型切换,sh是主流使用的,输入csh后没有显示不过也是切换了的。
另外,vim /etc/passwd ,伪用户是nologin不允许登陆,如果写的是具体的命令那么代表只能执行这一个命令且不允许登陆,例如shutdown是只能执行shutdown这一个命令。
二.脚本执行方式
1.
如果输出的话有空格,要用双引号括起来,但是如果有!,!号是有特殊含义的,所以用单引号‘’来括起整句话。
\x61 是 a
2.第一个脚本,cd sh/ 写脚本
3. bash不用给执行权限,不用chmod
先赋予执行权限,然后输入绝对路径或者相对路径来执行脚本
用远程工具将windows的脚本传输到LINUX里面,执行脚本出现报错。
cat hello.h去看脚本内容,cat -A 是看详细内容,包括隐藏内容,发现末尾$,表示LINUX的换行符。
然后cat -A一下远程传输的脚本,发现有一些不一样,windows换行符和LINUX的不一样:
上面的是windows的换行符,下面的$是linux的换行符,因为不一样所以不能识别
用 dos2unix 加上文件名字,来进行格式转换
发现成功转换了
执行脚本之后:
提示:如果没有安装这个命令可以手动去安装一下。
三.bash基本功能
(一)历史命令及补全
- root 的历史命令 放在/root/.bash_history ,普通用户的历史命令放在 /home/.bash_history
用户登陆后,执行的命令不会放在历史命令保存文件中,而是会放在缓存中,等到用户退出系统之后,缓存中的命令会保存到历史命令保存文件中。
vim /etc/profile 去修改HISTSIZE,这个是最大条数,十万也可以,因为文本文件的大小是很小(几kb)。超过的命令会挤掉之前的命令。修改之后要重启或者()可以生效。
如果user开头的命令有多个,按一下Tab是不会出现的,再按一次Tab就会出现所有以user的命令,然后再打个a,按Tab,就自动补全了useradd。输入目录也同理。
(二)别名与快捷键 - 暂时生效
一般执行命令都要打绝对路径,但是由于有环境变量定义好的目录,所以我们只需要输入命令的名字,如 ls ,而不是 /bin/ls 。
用 whereis 去查询命令 ,发现 ls 有路径,这个路径是执行文件所在的位置。cd没有路径,只有帮助文档,因为 cd是 Bash 的内部命令。(shell本身自带的)
2.永久生效要写入配置
按照格式写
3.
(三)输入输出重定向
1.
2. 输出重定向是,将命令执行后的结果由在屏幕显示转移到文件里。
命令必须有输出,文件才有内容,2和>之间不能有空格
第一条和第三条结果一样,第二条和第四条结果一样。
这个命令相当于把结果直接扔进垃圾箱,不去看对或者错
3. 相当于由手动输出命令,转换到从文件里输入命令,给源码打补丁用
(四)多命令顺序执行与管道符
- 多命令顺序执行
冒号,就算中间的命令报错,也会依次去执行。
dd复制命令,可以复制文件系统和文件,一般用来拷贝磁盘。
下面是把zero文件写入testfile里面1k 大小 * 100000个数据块,并输出间隔的两次时间
2.管道符 : 命令必须有正确输出!
搜索命令grep,提取文件内容中的某些内容。
用例:ll -a 目录 :显示的文件名字是不分页,加more使其命令输出的内容分页。
netstat -an 显示了所有的网络服务,加 | grep “ESTABLISHED" 来显示本机正使用的网络
(五)通配符和其他特殊符号
- 除了 * 都是一个字符。
cd到tmp下,rm -rf * 删除tmp下的文件,
rm -rf /* 是删根目录。
2. 单引号里所有的特殊符号都是普通符号。双引号里面有特殊意义。
单引号就是字符,而双引号则输出的是值
反引号是在ESC下的符号,` 不过容易误查看成单引号,用$() 也是一样的。括命令。
$ 是输出变量的值,加了 / 是让其失去作用,只输出字符。
四.Bash变量
(一)用户自定义变量
1.
2. 默认是字符型
空格代表命令和对象的分割,不能随便写空格。
3. 用户自定义变量的 名字,类型 和 值都可以自己更改,
环境变量是系统定义好的,可以修改数值;另外环境变量也可以自己定义。
位置参数变量是定义好的,只能改值。不能自己新添加。
预定义变量也是定义好的,只能改值。不能自己新添加。
set查看的是所有变量,包括自己定义的,环境变量等等。
(二)环境变量变量
1.
2. export 变量名=变量值 是为了使子shell可以使用父shell的环境变量
(1)pstree 是查询进程的命令
pstree 上面有一个bash,再上面又有一个bash,即为本机的shell,然后再上面的sshd是远程连接工具。
输入exit,退出pstree上面的一个bash(临近的那个)
(2)实验,验证父shell的变量会在子shell中生效(只用命令,不写配置文件)
首先在当前shell(bash)中定义好环境变量和普通变量
输入set查看变量信息,发现都在里面,即都在当前shell里
然后创建子shell ,用pstree去看,子shell成功创建
用set去查看,只有环境变量在子shell里
(3) PATH
PATH是用冒号分割的路径,是系统寻找命令的路径。(tab的补全原理也是一样的)
将hello.sh脚本cp到/bin/下,然后输入脚本名字就可以直接执行。但不好。
PATH变量的叠加:虽然脚本没有复制到PATH默认的路径之中,但是将root路径放到PATH里了,不过这个只是临时有效,并没有写到配置文件中
(4)PS1
env命令里面是看不到PS1的,只能那个用set查看,set:
PS1不是严格的环境变量,而是系统预留出来的用来定义系统环境的一个环境变量,是环境变量的一个子分支。
(三)位置参数
1.
$ 0 是命令本身
(2).
(3) $# 是不包括命令的所有参量的数目。
(四)预定义变量
1.
(1) $? 正确执行是0,错误信息都有对应的输出
(2) $ $ 和 $!
2.
(五)数值运算和运算符
1.
注意 $(expr $aa + $bb) 中的 + 两端必须有两个空格。
$(( $a + $b)) 的加号两端有没有空格不影响。
3.数值越小,优先级越高
(六)变量测试与内容替换
五.环境配置文件
(一)简介
- source 空格 配置文件
. 空格 配置文件
(点是sourse的缩写)
2. 环境变量
下面这个是环境变量的追加,不过只是临时生效,并没有写到配置文件里
环境变量所在的配置文件:
(二)作用
1.环境变量的调用是有优先级的
赋值在这几个文件中,是后面的覆盖前面的,但是可以用追加,这样就不会进行覆盖。
把配置写在哪个文件其实都是可以的。
(1)/etc/profile 详解:
打开 /etc/profile 这个文件去查看内容
/etc/profile.d/*.sh 目录下的文件:
重点关注文件 lang.sh,打开lang.sh 文件,文件内容里有这样一个文件:/etc/sysconfig/il8n
打开这个文件 /etc/sysconfig/il8n ,它是保存系统默认语言环境配置的文件
(2) .bash_profile
打开这个文件进行查看:
(3)那么接下来查看 .bashrc :
(4)打开/etc/bashrc查看,内容很长(跟第一个文件很像),重点查看两个内容:
登陆shell也会读取这个文件的一部分内容,读取的就是PS1
(三)其他配置文件和登陆信息
1.
2. 输入history命令输出的是包括缓存里的命令的命令表;而cat 下面这个文件里保存的是已经保存好的命令表(不包括缓存)
3. 只对本地终端生效。
4.远程登陆终端只能写纯文本信息,上面本地终端的欢迎信息都是不适用的。
打开/etc/ssh/sshd_config ,在#Banner下面输入Banner /etc/issue.net
写完后记得重启网络服务: service sshd restart
- 登陆后,尽量不要使用中文,如果没有安装中文插件会导致乱码。
六.正则表达式 - 文件内容 支持正则;文件名字 支持通配。
通配:完全匹配 ls aa只能查到aa
正则 : 包含匹配
2.
第一个 a*没有任何意义。 行
grep -n “^$” 文件名 可以显示空白行都在第几行
在ASCII表里,小写字母要放在大写字母前
上面的是以数字开头的行;下面的是不以数字开头的行,不过没有空行,因为空行是以换行符为开头的。
因为 . 表示一个字符,“. $" 表示以任意字符为结尾的行,也就是筛出了空行。
七.字符截取命令
(一)cut命令
1.
中间是制表符Tab,不能是空格,不然cut不能提取
提取第二列;2和4列
在passwd文档,分割符是冒号,提取1,3列提取1,3列:
(1)用例:只有root和普通用户的shell是 /bin/bash,伪用户不是/bin/bash
(2)局限分隔符
(二)printf命令
1.
全部当成一个字符串
只把第一个当作输出字符串的命令符,后面的全部当作字符串
单引号括起来,连续输出两个字符串,每个字符串有三个字符
两个字符串之间加了换行符
printf 后面不能加文件名字来输出文件内容 ,printf不能和管道符连用
调整格式来使输出更美观:
注意print和printf! print只在awk中可以使用!
(三)awk命令
1.
没有条件就直接执行,因为单引号已经被占用了,所以 为了方便辨识,命令里面用双引号将特殊符号括起来。
df查询系统分配情况,awk命令可以和管道符连用,且可以识别空格。
print在LINUX里是没有的,只在awake命令里存在,且默认在末尾加换行符。
BEGIN的作用是,在读取第一行数据前先进行处理。。
END则相反,是最后执行某个操作
指定分隔符用 FS
awk默认是先读入第一行数据,然后再处理
加BEGIN:在读入第一行数据前,先进行让冒号做分隔
(四)sed命令
- sed支持管道符输出,不需要先将内容保存到某个文件里,就可以进行修改
sed 和 vi 不同之处在于,它能对命令输出的结果进行处理
不加 - i ,文件并不会更改,只是对输出进行了更改;加-i会导致文件本身也被更改。
(1)查看行 一般都要加 -n ,不加 -n会把所有的行都输出
(2)删除
(3) 行的添加
第二行后追加一行
第二行前加入行
行替换
(4)字符串的替换
八.字符处理命令
- sort默认按照字母顺序排
只有-t的这个排序并没有把数字当作数值,而是当作字符,以第一个数字的大小做排序
加-n,把第三个字段当作数值
- wc
九.条件判断
- 判断文件类型
【空格 -e 文件名 空格】,用echo $? 来判断上一条是否有正确输出
2. 判断文件权限
只要所有者所属组其他人有一个有w权限,就会显示有w权限
3.
创建两个文件的硬链接
ll看不到它们是否为硬链接
可以用看i节点
用程序去判断两者是否为硬链接:
4.
中括号和里面的内容要有空格
5.
6.
十.流程控制
(一)if
1.
虽然写简单的脚本的时候不需要写 #!/bin/bash , 但是当有嵌入语句,例如人机交互时用到其他的语言,不是shell语句时就会出现问题。所以一般都需要写 #!/bin/bash
1.例子: 备份mysqi数据库
2. ps aux | grep httped 来判断阿帕奇是否正在运行时不准确的,因为阿帕奇可能卡死了,但是进程仍然显示,所以是不准的。
用netstart -tlum 来查看是否有80端口,但也不能确认阿帕奇是否正确运行。只是确认阿帕奇启动了。而且其他网络服务也可能使用80端口,所以不好。安装nmap命令
扫描开启的端口: nmap -sT 192.168.1.156
4.
可以用echo $? 来输出返回值去看
(二)case
1.
(三)for
1.
(四)while
- while
- until
命令ls,然后直接输出,这个不是不需要运算,而是shell帮你运算完的,所以shell不适合做大量的数据运算,效率低。