Shell基础

文章目录

  • Shell基础
    • 1. Shell版本介绍
      • 1. Shell脚本
        • 1. 什么是Shell
        • 2. shell作用详析
        • 3. 常用的shell类型
        • 4. shell脚本格式
      • 2. shell和shell脚本的区别
      • 3. 交互式shell和非交互式shell
      • 4. 运行shell脚本的两种方法
        • 1. 作为可执行的程序
        • 2. 作为解释器参数
      • 5. 查询指令是否为内建命令
    • 2. shell脚本常用的命令
      • 1. 常用命令
        • 1. cat,head,tail命令
        • 2. find命令
        • 3. 计划任务crond和crontab
        • 4. & 命令
        • 5. nohup命令
        • 6. shell的通配符
        • 7. echo命令
        • 8. read命令
        • 9. | 管道命令
          • 1. 管道命令的两个作用
        • 10. 重定向(文件描述符)
        • 11. tee命令
        • 12. sort命令
        • 13. uniq命令(默认去掉连续的重复值)
        • 14. grep命令
        • 15. cut命令(截取)
        • 16. tr命令(替换)
        • 17. wc命令
        • 18. basename命令
        • 19. split命令(分割文件)
        • 20. join命令
        • 21. paste用法
        • 22. eval命令
        • 23. date命令
        • 24. logger命令
        • 25. bc命令(支持小数运算)
      • 2. 练习
      • 3. 作业
    • 3. shell脚本基础支持及变量
      • 1. 基础知识
      • 2. 变量
        • 1. 环境变量
        • 2. 预定义变量
        • 3.位置变量
        • 4.自定义变量
          • 1. 第一类 环境变量
          • 2. 第二类 预定义变量
          • 3. 第三类 位置变量
          • 4. 第四类 自定义变量
        • 3. 变量命名规则
        • 4. 使用变量
        • 5. 只读变量
        • 6. 删除变量
      • 3. 函数库定义
        • 1. read命令的使用
        • 2. 通配符
    • 4. Test命令及判别语法
      • 1. test命令的使用
      • 2. 条件判断语句
      • 3. 练习
      • 4. if语句的嵌套
      • 5. 作业及练习
    • 5. 循环语法
      • 1. for循环语句
      • 2. select循环
      • 3. while和until循环
      • 4. until语法
    • 6. case分支语法及函数
      • 1. case语法结构
      • 2. 函数的参数
        • 1. 函数外的参数也能被函数调用
        • 2. 变量在函数内 外边也能调用
        • 3. 只在函数里调用 外部看不到 隔离变量
        • 4. 给函数传递参数
        • 5. 如果命令参数传递给函数
      • 3. 练习脚本
      • 4. 练习和作业
    • 7. 变量替换及数组
      • 1. 变量替换
        • 1. ${parameter:-word}
        • 2. ${parameter:=word}
        • 3. ${parameter:+word}
        • 4. ${parameter:?message}
      • 2. 数组
        • 1. 普通数组
        • 2. 关联数组
        • 3. 练习
    • 8. ssh远程操作及终端控制
      • 1.tput命令
      • 2. 定位倒计时
      • 3. ssh远程脚本
        • 1. expect非交互式
          • 1. [#!/usr/bin/expect]
          • 2. [set timeout 30]
          • 3. [spawn ssh -l username 192.168.1.1]
          • 4. [expect "password:"]
          • 5. [send "ispass\r"]
          • 6. [interact]
        • 2. shell脚本嵌套expect脚本
    • 9. 正则表达式
      • 1.正则对照表
        • 1. 正则表达式分类
        • 2.Linux 中常用文本工具与正则表达式的关系
      • 2. 正则练习题
    • 10. SED
      • 1. sed的使用
        • 1. *匹配0到多个前边字符
        • 2. [...] 匹配方括号中的任意一个字符,^为否定匹配, -表示字符的范围
        • 3. {n,m\} 匹配出现的n到m次数, \{n\}匹配出现n次。\{n,\}匹配至少出现n次(看扩展)
        • 4. 扩展元字符
          • 1. + 匹配前面的正则表达式的一次出现或多次出现
          • 2. ? 匹配前面的正则表达式的零次出现或一次出现
          • 3. | 可以匹配前面的或后面的正则表达式(替代方案)
          • 4. {n,m} 匹配出现的n到m次数, {n}匹配出现n次。{n,}匹配至少出现n次
          • 5. 匹配一个字符出现0-1次 基本正则也可以实现.\{,1\}
        • 5. 寻址上的全局透视(定址)
        • 6. 删除命令d
        • 7.分组命令
        • 8. 练习
        • 9. 替换命令
          • 1. n 可以是1-512,表示第n次出现的情况进行替换
          • 2. g 全局更改
          • 3. w file 写入到一个文件file中(只保存替换后行)
          • 匹配交换第一第二个字符
        • 10. 删除
          • 1. 转换
          • 2. 打印
      • 2. 高级sed 命令
        • 1. 追加下一行
        • 2. 多行删除
        • 3. 多行打印
        • 4. 包含那一行
      • 3. 练习
    • 11. AWK
      • 1. AWK简介
      • 2. awk语法
        • 1.读前处理BEGIN{awk_cmd1;awk_cmd2}
        • 2.行处理:定址命令
        • 3. NR变量定址
        • 4.命令{print $0}
        • 5.读后处理END {awk_cmd1;awk_cmd2;}
      • 3. 操作符
        • 1. 赋值= ++ -- += -= /= *=
        • 2. 字段引用
        • 3. 转义序列
        • 4. awk引用shell变量
        • 5. 内置变量
      • 4. 练习题
      • 5. 流程控制
        • 1. 分支结构
          • 1. if (条件) 动作
        • 2. if(条件1)
        • 3. if(条件1)
        • 4. 读前处理和读后处理
        • 5. 循环语句
        • 6. 跳转语句
      • 6. 数组
        • 1. 自定义数组
        • 2. 循环产生数组和取出数组
        • 3. 利用数组实现行列互换
      • 7. awk的内置函数
        • 1. 算数函数
          • 1. sqrt函数(求平方根)
          • 2. rand函数
          • 3. srand函数
        • 2. 字符串函数
          • 1. sub和gsub函数使用(替换字符)
          • 2. index函数(查找字符)
          • 3. length函数(计算长度)
          • 4. substr函数(截取字符串)
          • 5. match函数(正则匹配查找)
          • 6. split函数(字符分割)
        • 3. 一般函数
          • 1. close函数
          • 2. getline函数
          • 3. system函数
        • 4. 时间函数
          • 1. 创建时间格式
          • 2. strftime日期和时间格式说明符
        • 5. printf函数
      • 8. 练习

1. Shell版本介绍

1. Shell脚本

1. 什么是Shell

现在我们使用的操作系统(windows,Mac OS,Android,iOS等)都是带图形界面的,简单直观,容易上手,对于专业用户(程序员,网管等)和普通用户都非常适用;计算机的普及离不开图形界面。
然而计算机的早期并没有图形界面,我们只能通过一个一个命令来控制计算机,这些命令有成百上千之多,且不说记住这些命令是十分困难,每天面对没有任何色彩的黑屏本身就是一件枯燥的事情;这个时候的计算机还远远谈不上炫酷和普及,只有专业人士才能使用。
对于图形界面,用户只需要点击某个图标就能启动某个程序;对于命令行,用户输入某个程序的名字(可以看做一个命令)就能启动某个程序。这两者的基本过程都是类似的,都需要查找程序在硬盘上的安装位置,然后将他们加载到内存运行。换句话说,图形界面和命令行要达到的目的是一样的,都是让用户控制计算机。然而,真正能够控制计算机硬件(CPU 内存 显示器)的只有操作系统内核(kernel),图形界面和命令行只是架设在用户和内核之间的一座桥梁。
由于安全 复杂 繁琐的原因,用户不能直接接触内核(也没有必要),需要另外开发一个程序,让用户直接使用这个程序;该程序的作用就是就接收用户的操作(点击图标 输入命令),并进行简单的处理,然后再传递给内核。如此一来,用户和内核之间就多了一层"代理",这层"代理"既简化了用户的操作,也保护了内核。
用户界面和命令行就是这个另外开发的程序,就是这层代理"代理"。在linux下,这个命令行就叫做shell

​ Shell Script,Shell脚本与Windows/Dos下的批处理相似,也就是用各类命令预先放入到一个文件中,方便一次

性执行的一个程序文件,主要是方便管理员进行设置或者管理用的。但是它比Windows下的批处理更强大,比用

其他编程程序编辑的程序效率更高,毕竟它使用了Linux/Unix下的命令。

​ 换一种说法也就是,shell script是利用shell的功能所写的一个程序,这个程序是使用纯文本文件,将一些shell

的语法与指令写在里面,然后用正规表示法,管线命令以及数据流重导向等功能,以达到我们所想要的处理目的

2. shell作用详析

Shell除了能解释用户输入的命令,将他传递个内核,还可以:
1.调用其他程序,给其他程序传递数据或者参数,并获取程序的处理结果
2.在多个程序之间传递数据,把一个程序的输出作为另一个程序的输入
3.shell本身也可以被其他程序调用
由此可见,shell是将内核,程序和用户连接了起来Shell本身支持的命令并不多,但是他可以调用其他程序吗,每一个程序就是一个命令,这使得Shell命令的数量可以无限扩展,其结果就是shell功能非常的强大,完全能够胜任Linux的日常管理工作,如文本或者字符串检索,文件的查找或创建,大规模软件的自动部署,更改系统设置,监控服务器性能,发送报警邮件,抓取网页内容,压缩文件等。Shell并不是简单地堆砌命令,我们还可以在shell中编程,这和使用c++,Java,python等常见的编程语言没什么两样shell虽然没有C/C++,java,Python强大,但是也支持了基本的编程元素,例如:if..else选择结构,switch..case开关语句,for,while,util循环
变量,数组,字符串,注释,加减乘除,逻辑运算等概念
函数,包括用户自定义的函数和内置函数,例如(print,export eval)站在这个角度讲,Shell 也是一种编程语言,它的编译器(解释器)是 Shell 这个程序。我们平时所说的 Shell,有时候是指连接用户和内核的这个程序,有时候又是指 Shell 编程。Shell 主要用来开发一些实用的、自动化的小工具,而不是用来开发具有复杂业务逻辑的中大型软件,例如检测计算机的硬件参数、一键搭建Web开发环境、日志分析等,Shell 都非常合适

3. 常用的shell类型

sh、bash、csh、tcsh、ashsh
sh 的全称是 Bourne shell,由 AT&T 公司的 Steve Bourne开发,为了纪念他,就用他的名字命名了。
sh 是 UNIX 上的标准 shell,很多 UNIX 版本都配有 sh。sh 是第一个流行的 Shell。csh
sh 之后另一个广为流传的 shell 是由柏克莱大学的 Bill Joy 设计的,这个 shell 的语法有点类似C语言,所以才得名为 C shell ,简称为 csh。
Bill Joy 是一个风云人物,他创立了 BSD 操作系统,开发了 vi 编辑器,还是 Sun 公司的创始人之一。
BSD 是 UNIX 的一个重要分支,后人在此基础上发展出了很多现代的操作系统,最著名的有 FreeBSD、OpenBSD 和 NetBSD,就连 Mac OS X 在很大程度上也基于BSD。tcsh
tcsh 是 csh 的增强版,加入了命令补全功能,提供了更加强大的语法支持。ash
一个简单的轻量级的 Shell,占用资源少,适合运行于低内存环境,但是与下面讲到的 bash shell 完全兼容。bash
bash shell 是 Linux 的默认 shell,本教程也基于 bash 编写。
bash 由 GNU 组织开发,保持了对 sh shell 的兼容性,是各种 Linux 发行版默认配置的 shell。
bash 兼容 sh 意味着,针对 sh 编写的 Shell 代码可以不加修改地在 bash 中运行。尽管如此,bash 和 sh 还是有一些不同之处:
一方面,bash 扩展了一些命令和参数;
另一方面,bash 并不完全和 sh 兼容,它们有些行为并不一致,但在大多数企业运维的情况下区别不大,特殊场景可以使用 bash 代替 sh。

4. shell脚本格式

shell 脚本的格式
Shell 脚本文件的名称可以任意,但为了避免被误以为是普通文件,建议将 .sh 后缀加上,以表示是一个脚本文件。
shell 脚本中一般会出现三种不同的元素:
第一行的脚本声明(#!)用来告诉系统使用哪种 Shell 解释器来执行该脚本;
第二行的注释信息(#)是对脚本功能和某些命令的介绍信息,使得自己或他人在日后看到这个脚本内容时,可以快速知道该脚本的作用或一些警告信息;
第三、四行的可执行语句也就是我们平时执行的 Linux 命令了。

2. shell和shell脚本的区别

​ shell是什么呢?确切一点说,Shell就是一个命令行解释器,它的作用就是遵循一定的语法将输入的命令加以解

释并传给系统。它为用户提供了一个向Linux发送请求以便运行程序的接口系统级程序,用户可以用Shell来启动、

挂起、停止甚3至是编写一些程序。 Shell本身是一个用C语言编写的程序,它是用户使用Linux的桥梁。Shell既是

一种命令语言,又是一种程序设计语言(就是你所说的shell脚本)。作为命令语言,它互动式地解释和执行用户输入

的命令;作为程序设计语言,它定义了各种变量和参数,并提供了许多在高阶语言中才具有的控制结构,包括循环

和分支。它虽然不是 Linux系统内核的一部分,但它调用了系统内核的大部分功能来执行程序、创建文档并以并行

的方式协调各个程序的运行。

3. 交互式shell和非交互式shell

​ 交互式模式就是shell等待你的输入,并且执行你提交的命令。这种模式被称作交互式是因为shell与用户进行交

互。这种模式也是大多数用户非常熟悉的:登录、执行一些命令、签退。当你签退后,shell也终止了。

​ shell也可以运行在另外一种模式:非交互式模式。在这种模式下,shell不与你进行交互,而是读取存放在文

件中的命令,并且执行它们。当它读到文件的结尾,shell也就终止了。

如下

简单的实现系统巡检的命令
date
free –m
df –Th
写成一个简单的脚本test.sh

#!/bin/bash
date
free –m
df –Th
[root@master ~]# chmod +x test.sh
[root@master ~]# ./test.sh

4. 运行shell脚本的两种方法

1. 作为可执行的程序

给.sh文件可执行权限,然后./该名字执行即可 如:
[root@localhost ~]# vim test.sh
[root@localhost ~]# ./test.sh
Hello World test.sh文件里面写的内容为
#!/bin/bash
echo "Hello World !"注意事项:
一定写成./test.sh,而不是test.sh,运行其他二进制的程序也一样,直接写成test.sh,linux系统会去path寻找有没有叫test.sh的,而只有/bin./sbin,/usr/sbin等都在path里,如果当前目录不在path里面,写成test.sh是会找不到命令的,要用./test.sh告诉系统,就在当前目录找。

2. 作为解释器参数

运行这种方式是,直接运行解释器,其参数就是shell脚本的文件名 如/bin/sh test.sh
/bin/php test.php这种方式运行的脚本,不需要在第一行指定解释器信息,写了也没用。

5. 查询指令是否为内建命令

type命令可以查看

type [-参数] name

选项和参数:

​ : 不加任何参数时,type会显示出name是尾部指令还是bash的内建命令

-t : 当加入-t参数时,type会将name以底下这些字样显示其意义

​ file --------------> 外部指令

​ alias ------------> 设置的别名 可以在shell和全局配置文件中添加或修改

​ builtin ------------> bash内建的指令

-p : 如果后面接的name为外部指令时,才会显示完整的文件名

-a : 会由PATH变量定义的路径中,将含有name的指令都列出来,包含alias

[root@localhost ~]# type ls
ls is aliased to `ls --color=auto'   # 未加任何的参数,列出ls的具体使用情况
[root@localhost ~]# type -t ls
alias                                # 加入-t参数,直接返回其意义,指明ls是设置的别名
[root@localhost ~]# type -a ls
ls is aliased to `ls --color=auto'   # 最先使用alias
ls is /usr/bin/ls                    # 找到外部指令ls的位置
[root@localhost ~]# type cd
cd is a shell builtin                # shell的内建命令
[root@localhost ~]#

注:当命令过于长一行写不下或者是看着不舒服想要换行书写时需要在最后面的命令上加入反斜杠 \换行书写即可。

[root@localhost ~]# cat  /etc/sysconfig/network-scripts/ifcfg-ens33 \
> >> a.txt
[root@localhost ~]# vim a.txt

2. shell脚本常用的命令

1. 常用命令

1. cat,head,tail命令

1 求/etc/passwd文件第20行内容

[root@manager test1]# cat -n /etc/passwd | head -20 | tail -1

rev,tac命令

rev左右颠倒

tac上下颠倒

2. find命令

常用选项-name-type-user-nouser-group-nogroup-mtime-size

可以使用 -o 或者 -a 连接多个条件

可以使用-exec或者-ok来执行shell命令

 find /etc/ -name hosts -exec cp {} /tmp/ \;
如: find /var/logs -type f -mtime +7 -exec rm {} \;

xargs

​ 在使用find命令的- exec选项处理匹配到的文件时, find命令将所有匹配到的文件一起传递 给exec执行。不幸

的是,有些系统对能够传递给 exec的命令长度有限制,这样在 find命令运行几分钟之后,就会出现溢出错误。错

误信息通常是“参数列太长”或“参数列溢出”。

如:
[root@manager home]#  find / -name "core" -exec file {} \;
[root@manager home]#  find / -name "core" | xargs  file

3. 计划任务crond和crontab

*/10 * * * *   脚本|命令

4. & 命令

当在前台运行某个作业时,终端被该作业占据;而在后台运行作业时,它不会占据终端。

xclock -update 1 & 后台运行

关闭终端程序也会关闭

5. nohup命令

​ 如果你正在运行一个进程,而且你觉得在退出帐户时该进程还不会结束,那么可以使用 nohup命令。该命令可以在你退出帐户之后继续运行相应的进程。 nohup就是不挂起的意思( nohang up)。

该命令的一般形式为

nohup command &nohup xclock -update 1 &

6. shell的通配符

* 可以显示所有的匹配内容
? 匹配字符(可以是未知的字符)
[...]和[!...]  [a-z] [0-9] [!a12d]
{..} 

7. echo命令

双引号和单引号的区别
单引号
-e 使转义符生效 如: 解释\t \n含义
-n 不换行输出

字颜色:30—–37
echo -e “\033[30m 黑色字 \033[0m”
echo -e “\033[31m 红色字 \033[0m”
echo -e “\033[32m 绿色字 \033[0m”
echo -e “\033[33m 黄色字 \033[0m”
echo -e “\033[34m 蓝色字 \033[0m”
echo -e “\033[35m 紫色字 \033[0m”
echo -e “\033[36m 天蓝字 \033[0m”
echo -e “\033[37m 白色字 \033[0m”字背景颜色范围:40—–47
echo -e “\033[40;37m 黑底白字 \033[0m”
echo -e “\033[41;37m 红底白字 \033[0m”
echo -e “\033[42;37m 绿底白字 \033[0m”
echo -e “\033[43;37m 黄底白字 \033[0m”
echo -e “\033[44;37m 蓝底白字 \033[0m”
echo -e “\033[45;37m 紫底白字 \033[0m”
echo -e “\033[46;37m 天蓝底白字 \033[0m”
echo -e “\033[47;30m 白底黑字 \033[0m”改变提示符文件的颜色
[root@manager home]# echo -e "\033[40;32m"报警声音
[root@manager home]# echo -e "\007 the bell ring"printf命令
[root@manager home]# printf aa
aa[root@manager home]# printf "aa\n"
aa格式化输出
[root@manager home]# printf "%s,%s,%d\n" hello world 123
hello,world,123%s  字符串  %d十进制整数

8. read命令

​ 可以使用read语句从键盘或文件的某一行文本中读入信息,并将其赋给一个变量。如果只指定了一个变量,那

么 read将会把所有的输入赋给该变量,直至遇到第一个文件结束符或回车。

赋值

[root@manager home]# read name
zhangsan
[root@manager home]# echo $name
zhangsan

赋多值

[root@manager home]# read firstname lastname
huibin zhang
[root@manager home]# echo $firstname $lastname
huibin zhang

交互式

[root@manager home]# read -p "input a num: " var
input a num: 123
[root@manager home]# echo $var
123

9. | 管道命令

​ 管道(Pipe)实际是用于进程间通信的一段共享内存. 创建管道的进程称为管道服务器,连接到一个管道的进程为

管道客户机

1. 管道命令的两个作用

1.管道两边产生两个子进程

2.前一个进程的标准输出和后一个进程的标准输入

注意以下情况不能赋值

[root@7-1 tmp]# read a
fdsa
[root@7-1 tmp]# echo $a
fdsa
[root@7-1 tmp]# echo 456 | read b
[root@7-1 tmp]# echo $b【注】因为管道两边产生的是两个子进程,所以不能进行赋值输出而分开写则是输出$a是read a的子进程,这样可以进行赋值并以原值输出ps -f | cat
UID    PID PPID C STIME TTY     TIME CMD
root   14412 14405 0 04:56 pts/3  00:00:00 -bash
root   15485 14412 0 05:53 pts/3  00:00:00 ps -f
root   15486 14412 0 05:53 pts/3  00:00:00 cat
3个进程没有任何父子进程关系
如图:
bash ps -f | cat
1000 2000   3000echo 123 | read a
bash
|______ps -f >
|______cat <bash
|______echo 123 >
|______read a <

10. 重定向(文件描述符)

​ 文件描述符:进程连接到文件时,获得的一个标记.当进程操作文件时,首先打开文件 获得打开文件的一个状态,给它

一个标记 成为文件描述符

0标准输入
1标准输出
2标准错误输出

> >> 定向符(重定向) >覆盖 >>追加

1> 标准正确输出,文件存在则覆盖,不存在则创建

1>> 标准正确输出,文件存在则追加,不存在则创建

2> 标准错误输出,文件存在则覆盖,不存在则创建

2>> 标准错误输出,文件存在则追加,不存在则创建

&> 标准正确和标准错误输出,文件存在则覆盖,不存在则创建

cat < /dev/sda > /dev/null 测试改变文件描述符

ls >cleanup.out 2>&1

在上面的例子中,我们将 ls命令的输出重定向到 cleanup .out文件中,而且其错误也 被重定向到相同的文件中。

2>&1 标准错误输出定向到标准正确输出

< 输入重定向 后边跟的是文件 > >>

<< here document 后边跟的是一个文本

如下
cat > x.txt << EOF
\> sdfsadlkf
\> asdfsadhf
\> asfdhkasfd
\> EOF ------------直到遇到EOF结束[root@manager tmp]# fdisk /dev/sda <<EOF
\> n
\>
\> +200M
\> w
\> EOF<<<here string 后边跟字符串 直接交给文本 如:
cat >x.txt <<<asdadad
cat x.txt\> >> < << <<<

11. tee命令

​ tee命令作用可以用字母 T来形象地表示。它把输出的一个副本输送到标准输出,另一个 副本拷贝到相应的文件

中。如果希望在看到输出的同时,也将其存入一个文件, 这种情况可以使用tee命令

如:
[root@manager home]# who | tee who.out
root     pts/1        2016-09-18 07:50 (192.168.10.102)
[root@manager home]# cat who.out
root     pts/1        2016-09-18 07:50 (192.168.10.102)[root@manager home]# find /etc -name hosts | tee aa.txt
/etc/hosts
[root@manager home]# cat aa.txt
/etc/hosts

简而言之就是tee命令既可以让结果输出在文件里面也可以在终端中显示。

12. sort命令

[root@manager tmp]# cat aa.txt
2
4
3
21
90
78
45
23
2
3
5
1
[root@manager tmp]# sort aa.txt   默认排序是按着第一字符大小进行排序
1
2
2
21
23
3
3
4
45
5
78
90
[root@manager tmp]# sort -n aa.txt  -n参数就是按着整体排序
1
2
2
3
3
4
5
21
23
45
78
90
[root@manager tmp]# sort -n -r aa.txt    按完整数字排序 降序
90
78
45
23
21
5
4
3
3
2
2
1
[root@manager tmp]# sort -u aa.txt  去掉重复值
1
2
21
23
3
4
45
5
78
90[root@manager tmp]# sort -t: -k3nr /etc/passwd

13. uniq命令(默认去掉连续的重复值)

[root@manager tmp]# cat aa.txt
2
4
4
3
3
21
90
78
45
23
2
3
5
1
[root@manager tmp]# uniq aa.txt  连续的去掉
2
4
3
21
90
78
45
23
2
3
5
1
[root@manager tmp]# uniq -u aa.txt  显示未重复值
2
21
90
78
45
23
2
3
5
1
[root@manager tmp]# sort -n aa.txt  | uniq -u 排序去重
1
5
21
23
45
78
90[root@manager tmp]# sort -n aa.txt  | uniq -d  显示重复行
2
3
4
[root@manager tmp]# sort -n aa.txt  | uniq -d -c  统计重复次数2 23 32 4

14. grep命令

--color
-i   忽略大小写
-A  后几行
-B  前几行
-C  前后几行
-r   递归目录
-l   只显示匹配文件名
-x  完全一样
-n  显示行号
[root@manager tmp]# grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin[root@manager tmp]# grep ^root /etc/passwd
root:x:0:0:root:/root:/bin/bash[root@manager tmp]# grep halt$ /etc/passwd
halt:x:7:0:halt:/sbin:/sbin/halt[root@manager tmp]# grep -A 2 root /etc/passwd
[root@manager tmp]# grep -B 2 root /etc/passwd
[root@manager tmp]# grep -C 2 root /etc/passwd统计存在root的行数
[root@manager tmp]# grep -c root /etc/passwd
2过滤root用户,并显示行号
[root@manager tmp]# grep -n root /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
11:operator:x:11:0:operator:/root:/sbin/nologin[root@manager tmp]# grep -r root /etc/  过滤所有文件
[root@manager tmp]# grep -rl root /etc/  列出文件名
[root@manager farm]# grep -rl  'localhost' /usr/local/apache/htdocs/farm/[root@manager tmp]# cat aa.txt
abc
ABC
xyz
XYZ
[root@manager tmp]# grep abc aa.txt
abc
[root@manager tmp]# grep -i abc aa.txt
abc
ABC[root@manager tmp]# grep -ix abc aa.txt
ABC
[root@manager tmp]# grep -i ^abc$ aa.txt
ABC

15. cut命令(截取)

[root@manager tmp]# cat aa.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@manager tmp]# cut -c 1 aa.txt
r
b
d
a
l
[root@manager tmp]# cut -c 1,3,5 aa.txt
ro:
bnx
deo
amx
l::
[root@manager tmp]# cut -c 1-5 aa.txt
root:
bin:x
daemo
adm:x
lp:x:[root@manager tmp]# cut -d: -f 1 aa.txt
root
bin
daemon
adm
lp[root@manager tmp]# cut -d: -f 1,3,5 aa.txt
root:0:root
bin:1:bin
daemon:2:daemon
adm:3:adm
lp:4:lp
[root@manager tmp]# cut -d: -f 1-5 aa.txt
root:x:0:0:root
bin:x:1:1:bin
daemon:x:2:2:daemon
adm:x:3:4:adm
lp:x:4:7:lp[root@manager tmp]# cat cc.txt
aa cc
kk hh
[root@manager tmp]# cut -d' ' -f 1 cc.txt
aa
kk

16. tr命令(替换)

• 大小写转换。
• 去除控制字符。
• 删除空行。

[a-z] a-z内的字符组成的字符串。

[A-Z] A-Z内的字符组成的字符串。

[0-9] 数字串

- s选项去掉重复字符

默认是将连续的字符去除,只保留一个
[root@manager etc]# echo "hellooooooo worlddddddd" | tr -s "[a-z]"
helo world[root@manager tmp]# cat tt.txt
hellooooooooooooo worldddddddddddddddddddd
[root@manager tmp]# cat tt.txt | tr -s '[a-z]'
helo world以原样hello world显示就要将l选项筛选出去,使他就算是连续也不会被去除
[root@manager tmp]# cat tt.txt | tr -s '[a-k][m-z]'
hello world删除空行
[root@manager home]# tr -s "[\n]" < aa.txt
1.robin 19
2.zorro  30
3.tom  35大小写转换
[root@manager home]# tr "[a-z]" "[A-Z]" < cc.txt
1.ROBIN MAN
2.ZORRO MAN
3.TOM MAN如果需要删除文件中^M,并代之以换行。使用命令:
tr -s "[\r]" "[\n]" < file.txt

17. wc命令

-l
-w
-c

[root@manager ~]# wc -l /etc/passwd
49 /etc/passwd[root@manager tmp]# wc -w kk.txt
3 kk.txt[root@manager tmp]# wc -c kk.txt
6 kk.txt

18. basename命令

显示末尾文件名

[root@manager ~]# basename /var/log/messages
messages
[root@manager ~]# basename /var/log/
log

19. split命令(分割文件)

[root@manager home]# cp /etc/passwd ./
[root@manager home]# split -l 2 passwd
[root@manager home]# ls
passwd  xaa  xab  xac  xad  xae  xaf  xag  xah  xai  xaj
[root@manager home]# cat xaa
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin[root@manager tmp]# cat passwd | split -l 10
[root@manager tmp]# ls
passwd  xaa  xab  xac  xad  xae[root@manager tmp]# split -b 1 aa.txt
[root@manager tmp]# ls
aa.txt  xaa  xab  xac  xad  xae  xaf

20. join命令

有匹配域
[root@manager home]# cat aa.txt
1.robin 19
2.zorro  30
3.tom  35
[root@manager home]# cat cc.txt
1.robin man
2.zorro man
3.tom man
[root@manager home]# join aa.txt cc.txt
1.robin 19 man
2.zorro 30 man
3.tom 35 man

​ 如果一个文件与另一个文件没有匹配域时怎么办?这时 join不可以没有参数选项,经常指定两个文件的- a选

项。下面的例子显示匹配及不匹配域。

[root@manager home]# join -a1 -a2 aa.txt cc.txt
1.robin 19 man
2.zorro 30 man
3.tom 35 man
4.jerry man
[root@manager home]# join aa.txt cc.txt
1.robin 19 man
2.zorro 30 man
3.tom 35 man

21. paste用法

​ paste将按行将不同文件行信息放在一行。缺省情况下, paste连接时,用空格或tab键分隔 新行中不同文本,

除非指定- d选项,它将成为域分隔符。

[root@manager home]# paste aa.txt cc.txt
1.robin 19  1.robin man
2.zorro  30 2.zorro man
3.tom  35   3.tom man
4.jerry man

​ paste命令还有一个很有用的选项( -)。意即对每一个( -),从标准输入中读一次数据。 使用空格作域分隔

符,以一个4列格式显示目录列表。方法如下

[root@manager etc]# ls | paste -d" " - - - - - -

22. eval命令

eval命令是一直执行命令直至执行完毕停止

[root@manager home]# vim cc.txt
1.robin man
2.zorro man
3.tom man[root@manager home]# aa="cat cc.txt"
[root@manager home]# echo $aa
cat cc.txt
[root@manager home]# eval $aa
1.robin man
2.zorro man
3.tom man[root@7-1 tmp]# echo $aa
cat cc.txt
[root@7-1 tmp]# aa='cat cc.txt'
[root@7-1 tmp]# echo $aa
cat cc.txt
[root@7-1 tmp]# aa=`cat cc.txt`
[root@7-1 tmp]# echo $aa
1.robin man 2.zorro man 3.tom man1
[root@7-1 tmp]# eval $aa
bash: 1.robin: command not found...
[root@7-1 tmp]# 【注】若cc.txt中第一行是命令的话,则使用eval会继续执行第一条命令,然后输出结果在终端上而echo $aa不会执行文件的第一条命令,会将cc.txt文件中的信心全部输出出来。eval只执行文件中的一条命令,默认是第一行的。若要执行文件中别的命令则需要使用别的指令使eval定向到那条命令然后再执行。

23. date命令

[root@manager tmp]# date
2016年 09月 15日 星期四 01:20:48 CST
[root@manager tmp]# date +%F
2016-09-15[root@manager tmp]# date 月日时份年.秒
[root@manager tmp]# date -s "20161015 10:10:10"
2016年 10月 15日 星期六 10:10:10 CST[root@manager tmp]# date +%Y-%m-%d-%H-%M-%S
2016-09-20-13-58-09

24. logger命令

[root@manager tmp]# logger "hello i am robin"自定日志保存位置
[root@manager tmp]# vim /etc/rsyslog.conf
local5.*                                                /tmp/test.log
[root@manager tmp]# service rsyslog restart[root@manager tmp]# logger -p local5.err -t test  -f /tmp/test.log  hhhhhhh
-p日志级别
-t 标记
-f 日志位置

25. bc命令(支持小数运算)

整数

[root@manager ~]# bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
1+2
3
3-1
2
2*2
4
2/2
1
5%2
1
5^2
25

小数

[root@manager ~]# bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
scale=3  # 只有在输入此指令时才会使小数点后保留几位
7/3
2.333

进制转换

[root@manager ~]# bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
#ibase是input输入是几进制的数
#obase是output输出是几进制的数
ibase=10;obase=2
10
1010
2
10
ibase=8;obase=10
9
11
ibase=10;obase=16
11
B
上述和这种的都属于交互式操作

非交互式

[root@manager ~]# echo "1+2" | bc
3
[root@manager ~]# echo "scale=3;3/2" | bc
1.500
[root@manager ~]# echo "ibase=10;obase=2;7" | bc
111[root@manager tmp]# echo "obase=8;19" | bc
23
[root@manager tmp]# echo "obase=2;F" | bc
1111[root@manager tmp]# echo "2^10" | bc
1024

计算平方根

[root@manager ~]# echo "sqrt(100)" | bc
10

||逻辑或 前边命令失败执行后边命令
&&逻辑与 前边命令成功运行后边命令

pwd && echo ok
adfa && echo okpwd || echo ok
adfa || echo ok

2. 练习

1.统计当前系统中有多少个用户可以登录

[root@manager ~]# grep "/bin/bash$" /etc/passwd | wc -l
14
[root@manager ~]# grep -c "/bin/bash$" /etc/passwd
14
[root@manager ~]# cut -d: -f 7 /etc/passwd | grep bash | uniq -c14 /bin/bash

2.取ip地址

[root@manager ~]# ifconfig eth2 | head -2 | tail -1 | cut -d':' -f 2 | cut -d' ' -f 1
[root@manager ~]# ifconfig eth2 | grep Bcast | cut -d':' -f 2 | cut -d' ' -f 1
172.16.20.1
[root@manager ~]# ifconfig | grep Bcast | cut -d':' -f 2 | cut -d' ' -f 1
172.16.20.1
172.16.20.201

3.使用stat命令查看文件状态,然后截取时间

[root@manager ~]# stat install.logFile: "install.log"Size: 8003       Blocks: 16         IO Block: 4096   普通文件
Device: 802h/2050d  Inode: 130307      Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2016-09-09 06:29:21.250999892 +0800
Modify: 2016-09-09 06:30:57.320999775 +0800
Change: 2016-09-09 06:30:59.526999773 +0800取时间
06:29:21
06:30:57
06:30:59[root@manager ~]# stat /root/install.log | tail -3 | cut -d" " -f3 | cut -d'.' -f 1
18:02:07
09:54:49
09:54:49
[root@manager ~]# stat /root/install.log | tail -3 | cut -d" " -f1,3 | cut -d'.' -f 1
Access: 18:02:07
Modify: 09:54:49
Change: 09:54:49

4.将ip地址192.168.10.100转换成点分二进制

[root@manager ~]# echo "obase=2;192" | bc
11000000
[root@manager ~]# echo "obase=2;168" | bc
10101000
[root@manager ~]# echo "obase=2;10" | bc
1010
[root@manager ~]# echo "obase=2;100" | bc
11001005.将passwd文件按uid排序?按gid排序?
[root@manager ~]# sort -t: -k3n /etc/passwd
[root@manager ~]# sort -t: -k4n /etc/passwd

3. 作业

写一个 一键配置yum库脚本

[root@manager test1]# cat yum.sh
#!/bin/bash
#configure yum scripts#mount cdrom
umount /yum
mount /dev/cdrom /yum#configure yum
rm -rf /etc/yum.repos.d/*
touch /etc/yum.repos.d/yum.repo
cat > /etc/yum.repos.d/yum.repo <<EOF
[CentOS6.6]
name=server
baseurl=file:///yum
gpgcheck=0
enabled=1
EOF#test yum
yum clean all
yum makecache===========#!/bin/bash
mount -t iso9660 /dev/cdrom /mnt/
cd /etc/yum.repos.d/
mkdir old
mv CentOS-* old/
touch loacl.repo
cat > /etc/yum.repos.d/local.repo <<EOF
[local_iso]
name=local iso
baseurl=file:///mnt
enabled=1
gpgcheck=0
EOFcat >> /etc/fstab <<EOF
/dev/cdrom /mnt iso9660 defaults 0 0
EOFyum clean all
yum repolist

3. shell脚本基础支持及变量

1. 基础知识

1.shell脚本的格式注意事项

2.shell脚本文件的扩展名

3.shell脚本执行顺序以及产生后果(如出现错误)

a /tmp/testrm –rf $a/*

4.用户身份的不同执行脚本的区别

普通用户若想执行脚本最低权限为rx才可以执行root用户只需要x权限即可

5.shell种类的介绍(nologin和锁定区别)及用户切换切换shell方式(bash chsh -l)

nologin是不能进行远程登录
锁定是不允许登录

6.历史命令的介绍history

!! 执行历史命令中最后一条
!100 执行历史命令中的第一百条命令
!ser  执行历史命令中距离最后一条命令最近的以ser开头的命令
!$   执行最后一条命令
alt+. 使用上一条命令中的最后的指令 和使用 esc+。功能一样

7.Shell退出时执行的命令.bash_logout

8.别名的介绍alias(以及命令的回顾)

2. 变量

1. 环境变量

​ 环境变量是一个具有特定名字的对象,它包含了一个或者多个应用程序所将使用到的信息。例如path,当要求

系统运行一个程序而没有告诉它程序所在的完整路径时,系统除了在当前目录下面寻找此程序外,还应到path中

指定的路径去找。用户通过设置环境变量,来更好的运行进程

环境变量:系统在启动过程中预先指定好的一系列的变量.比如当前用户是谁 当前shell是什么 当前用户的家目录在

什么位置等等

2. 预定义变量

预定义变量:系统预定义好的 和进程名称 进程编号 进程参数 进程返回值相关

3.位置变量

位置变量和命令行参数相关

4.自定义变量

自定义变量(用户自己定义的变量)

1. 第一类 环境变量

环境变量 echo

env 查看所有环境变量

echo $变量名 输出变量

PATH
USER
HOME
HOSTNAME
PWD
UID
PS1
LANG=zh_CN.UTF8 (setup,yum groupinstall.系统时间)

set 查看所有变量(包括环境变量和非环境变量)

非环境变量:为用户定义的变量

export x=100 环境变量 可以被子进程所调用
y=200 非环境变量 不能被子进程所调用

环境变量和非境变量永久生效,写入配置文件

每个用户家目录下的环境变量配置文件:

.bash_history  保存用户执行过来历史命令,当用户退出时保存
.bash_logout  保存用户退出时执行的命令.bash_profile  保存用户定义环境和启动项目,用户执行命令时的搜索路径
.bashrc  保存用户别名和函数.bash_profile  登录级别环境配置文件
.bashrc  shell级别的环境配置文件/etc/bashrc 全局shell级别环境配置文件
/etc/profile 全局登录级别环境配置文件

登录时加载的配置文件顺序

/etc/profile
.bash_profile
.bashrc
/etc/bashrcquestion:
su - robin  和 su robin 切换帐号的区别:
answer:
1. su - robin 登录级别切换
2. su robin shell级别切换su - 切换用户后,同时切换到新用户的工作环境中
su   切换用户后,不改变原用户的工作目录,及其他环境变量目录用su -用户名的切用户的时候,他会把用户的环境变量也会读取出来,读取~/.bashrc文件
而su 不会

练习

1.当robin用户退出时,清除自己所有的历史命令

[root@manager robin]# vim /home/robin/.bash_logoutrm -rf /home/robin/.bash_historyhistory -c

2.设置别名myip 要求:所有用户可以调用这个别名

[root@manager robin]# vim /etc/bashrc
alias myip="ifconfig eth2 | grep Bcast | cut -d':' -f 2 | cut -d' ' -f 1"

3.当一个用户登录时将这个用户登录的用户名,时间写入到/tmp/login.txt文件

[root@manager robin]# vim /etc/profile
echo "$USER" 'login' `date`  >> /tmp/login.txt
2. 第二类 预定义变量

$0 $$ $# $? $*

$0 进程名(如:/etc/init.d/network)
$$ 进程号(/var/run 模拟系统结束进程)
$# 位置参数的数量
$* 所有位置参数的内容
$? 命令执行后的返回状态.0为执行正确,非0为执行错误

[root@7-1 ~]# cat test.sh
#!/bin/bash
echo $0    #  进程名(如:/etc/init.d/network)
echo $$    #  进程号(/var/run 模拟系统结束进程)
echo $#    #  位置参数的数量
echo $?    #  所有位置参数的内容
echo $*    #  命令执行后的返回状态.0为执行正确,非0为执行错误
[root@7-1 ~]# bash test
test/    test.sh
[root@7-1 ~]# bash test.sh
test.sh
2648
0
0[root@7-1 ~]# bash test.sh 1 2 3
test.sh
2649
3
0
1 2 3
[root@7-1 ~]#
3. 第三类 位置变量

位置变量: 和命令行参数相关 (命令后跟的参数$1-$9)

4. 第四类 自定义变量

自定义变量:当用户变量不够用时,自定义的变量

如下测试脚本

#!/bin/bash
cd /tmp
touch a.txt
ls –ld /tmp
du –sh /tmp改为
#!/bin/bash
$DIR=/tmp
cd $DIR
touch a.txt
ls –ld $DIR
du –sh $DIR

练习

1.计算器 四则运算

./脚本 1 + 2
3

再进一步完善脚本read 命令的使用

[root@7-1 ~]# vim sum.sh
#!/bin/bash
echo $(($1 $2 $3))
[root@7-1 ~]# bash sum.sh 1+2
3[root@7-1 ~]# vim sum.sh
#!/bin/bash
echo $(($*))
[root@7-1 ~]# bash sum.sh 1+2
3[root@7-1 ~]# vim sum.sh
#!/bin/bash
echo "scale=2;$* " | bc
[root@7-1 ~]# bash sum.sh 1+2
3[root@7-1 ~]# vim sum.sh
#!/bin/bash
read -p "number1:" num1
read -p "op: " op
read -p "number2: " num2
echo "scale=2;$num1 $op $num2" | bc[root@7-1 ~]# bash sum.sh
number1:1
op: +
number2: 3
42.算式运算符
+、-、*、/、()1.$((5+3))
2.$[ 5+3 ]3.expr操作符:
+、-、\*、/、%取余(取模)
expr 1 + 24.let操作
a=1;b=2
let c=$a+$b
echo $c

export作用范围
父子shell的说明,及变量的定义

a.sh
#!/bin/bash
echo IN a.sh’
aa=123
./b.shb.sh
#!/bin/bash
echo ‘IN b.sh’
echo $aa运行脚本方式的介绍
./a.sh
bash a.sh
source a.sh
. a.sh
source a.sh 和. a.sh【注】
source 和 . (点空格)作用是加载命令并不是执行,多用于加载函数库
./ bash 才是执行命令,可以直接执行可执行程序别名   内部命令    外部命令
[root@manager tmp]# type ls   别名
ls is aliased to `ls --color=auto'[root@manager tmp]# type useradd   外部 产生子进程
useradd is /usr/sbin/useradd[root@manager tmp]# type cd  内部  不产生子子进程在当前环境下运行
cd is a shell builtin别名>外部命令>内部利用当前的shell执行后边的脚本 如果没有外部命令 则不产生子进程
如测试脚本如下
cat aa.sh
\#!/bin/bash
cd /
pwd./ aa.sh
. aa.sh

3. 变量命名规则

在定义变量时,变量名不加美元符号($,php语言中的变量需要)
【注】 变量$后面是{},不是其他括号
your_name="123456789"【注】 变量名和等号之间不允许有空格变量名命名规则(和python类似):
1.命名只能使用英文字母,数字和下划线,首个字符不能以数字开头
2.中间不能有空格,可以使用下划线
3.不能使用标点符号
4.不能使用bash里的关键字(可用help命令查看保留关键字)变量设定规则:
1. 变量与变量内容以一个等号来连接
2. 等号两边不能直接接空格符号
3. 变量内容若有空格符号可以使用双引号或者单引号将变量内容结合起来。双引号内的特殊字符如$等,可以保持原有的特性单引号内的特殊字符只能为一般字符(纯文本)
4. 变量名称只能是英文字母和数字,但是开头不能为数字
5. 可以使用跳脱字符反斜杠将特殊符号变成一般字符。
6. 在一串指令的执行中,还需要使用反引号或者$指令
7. 若该变量为扩增变量内容时,则可以使用$变量名称或$(变量)累加内容 如:path="$path":/home/bin 或 path=${path}:/home/bin
8. 若变量需要执行其他子程序时,则需要export来是变量变为环境变量
9. 通常大写字符为系统的默认变量,自行设定的变量可以使用小写字符
10. 取消变量的方法使用unset unset 变量名
不仅显式直接赋值,还可以用语句给变量赋值  如:
for file in `ls /etc`
或
for file in $(ls /etc}
上述语句将/etc下目录的文件名循环出来

4. 使用变量

使用一个定义过的变量,只要在变量名前面加上美元符号($)即可:

your_name="123456"
echo $your_name
echo ${your_naeme}注:
变量名外面的花括号是可选的,加不加都行。加花括号是为了帮助解释器识别变量的边界。
如:
for i in natasha harry sarah;
doecho "I am ${i}_father"
done如果不给变量加上花括号,解释器会把 $i_father当成一个变量,但是其不存在的,所以输出结果就不是期待的那种情况。

已定义的变量,可以被重新定义

your_name="123"
echo $your_name
your_name="456"
echo $your_name
这样写是合法的,但第二次赋值的时候不能写$your_name="alibaba",使用变量的时候才加美元符($)。

5. 只读变量

使用readonly命令可以将变量定义为只读变量,只读变量的值不允许被改变

#!/bin/bash
myurl="https://www.google.com"
readonly myurl
myurl="https://www/baidu.com"运行脚本:
[root@localhost ~]# ./test.sh
./test.sh: line 4: myurl: readonly variable

6. 删除变量

使用unset命令可以删除变量,语法:

unset variable_name变量在删除后不能被再次使用,unset命令不能删除只读变量。实例:
#!/bin/sh
myUrl="https://www.runoob.com"
unset myUrl
echo $myUrl
myUrl1="https://www.baidu.com"
#unset myUrl1
echo $myUrl1[root@localhost ~]# vim test.sh
[root@localhost ~]# ./test.sh https://www.baidu.com

3. 函数库定义

函数库:将常用的变量定义到一个文件里 直接加载这个文件 就不用重复定义变量了

如系统中的确定与失败

子进程定义的变量能否被父进程集成

nologin shell 和 login shell
/etc/bashrc
/etc/bashrc
~/.bashrc
~/.bash_profile

1. read命令的使用

read命令:将脚本后边跟着的变量的值读取到脚本中
-p –t 参数的说明
如下边这个有趣的脚本

#!/bin/bash
read -p "请输入银行卡账号: " num
read -p "请输入银行卡密码: " -t 5 pass
echo 账号$num 密码$pass >> /tmp/haha.txtyum install postfix
service postfix restart#!/bin/bash
read -p "输入帐号: " account
stty -echo
read -p "输入密码: " -t 5  pass
stty echo
echo
echo "帐号:$account 密码:$pass" >> /tmp/login.txt
echo "帐号:$account 密码:$pass" | mail -s "auth" root@localhost

算式置换

a=10+20
a=$((10+20))

命令置换(将命令执行结果赋给变量)

a=`date +%m%d`
a=$(date +%m%d) 推荐
[root@manager test1]# file=`ls `date +%F``  报错
[root@manager test1]# file=$(ls $(date +%F))
[root@manager test1]# echo $file
2016-09-20

原因

a=`ls `date +%m%d`` 该赋值失败
a=$(ls $(date +%m%d ))

2. 通配符

通配符是shell解释的 正则表达式是命令解释的

*   匹配任所有字符
?   匹配一个字符
[]  匹配一个范围
{}  如touch abc{a,b,c}{1..3}.txt

变量的引用
echo 命令介绍
echo -n -e参数说明 “”’’说明 \n \t
echo $
echo ’$’

[root@manager test1]# echo hello world;i am robin 报错[root@manager test1]# echo "hello world;i am robin"
hello world;i am robin
[root@manager test1]# echo 'hello world;i am robin'
hello world;i am robin[root@manager test1]# name=robin
[root@manager test1]# echo 'hello world;i am $name'
hello world;i am $name
[root@manager test1]# echo "hello world;i am $name"
hello world;i am robin

4. Test命令及判别语法

1. test命令的使用

语法:test EXPRESSION 或者 [ EXPRESSION ]

字符串判断(用于看用户有没有输入指定的变量 指定用户输入目录 )

-n 字符段长度是否非零的 如果结果为真值 返回值为0 如果结果为假值返回值非0

例:判断两个文件名字是否一致

mkdir /a /b
touch /a/x.txt /b/x.txt
[ "/a/x.txt"="/b/x.txt"] 可定错误不同 目录名称不同
应为
[ "$(basename /a/x.txt)"="$(basename /b/x.txt)" ]

test 整数

eq 等于
ge 大于等于
gt 大于
le 小于等于
lt 小于
ne 不等于

test 文件

ef 两个文件有相同的设备编号和inode编号 (判断硬链接)
touch aa
ln aa bb
ls -i
456733 aa 456733 bb根据文件类型判断
-d 文件存在必须是个目录
-e 有文件名存在就行不管类型
-f 文件存在而且是个标准普通文件
-h 文件存在并且是否为符号链接文件
-r 判断文件权限是否有r权限
-w 写权限
-x 执行权限
【注】以上所有的命令都可以通过使用man手册进行查看,具体作用全部都有。

2. 条件判断语句

if cmd;如为真值
then
fi  结束 执行
如为假值则不执行例
if [ -f /etc/passwd ]
thenecho ok
fi若文件不存 则 不执行if useradd uu3
then id uu3
fi
添加成功则显示用户信息if [ -f /etc/ssh/sshd_config ]
then service sshd start
elseecho ssh is not install
fi

3. 练习

1.提示输入一个用户名字,判断该用户是否存在?存在显示其信息(uid gid 家目录 shell),不存在添加该帐号

#!/bin/bash
read -p "输入用户名: " username
if id $username &> /dev/null
thenecho "用户存在,显示信息"grep $username  /etc/passwd | cut -d':' -f 1,3,4,6,7
elseecho "用户$username不存在,添加用户"useradd $username
fi

2.提示输入文件路径及文件名,判断该文件是否存在,存在显示其详细信息,不存在创建该文件

[root@manager test1]# cat file.sh
#!/bin/bash
read -p "输入完整文件名: " file
if [ -f $file ]
thenecho "文件存在,显示文件信息"ls -l $file
elseecho "文件不存在,创建文件"touch $file
fi

4. if语句的嵌套

if cmd
then………
else if cmdthen ……….else………..fi
fiif语句的完整写法
if cmd1
thenrun cmd1-1run cmd1-2
elif cmd2
thenrun cmd2-1run cmd2-2
elif cmd3
then  run cmd3-1run cmd3-2
else
thenrun cmd4-1run cmd4-2
fi

100数字内猜数字游戏

#/bin/bash
guess=80
read -p "please insert yao number(range 1-100): " num
if [ $num -eq $guess ]
thenecho "you are win!!!!"
elseecho "you are lose!!!!"
fi

如果是猜随机数怎么办?($RANDOM).

正常情况应该为产生一个随机数,猜数人员有5次机会.这就需要用到循环语句,那么循环语句的结构式怎样的呢?带着上边的问题我们先学习一下循环语句,循环语句主要有两个循环语句for和while。

5. 作业及练习

1.判断tmp下是否存在普通文件aa.txt,文件存在则输出文件详细信息,文件不存在则创建文件

[root@7-1 work]# vim one.sh
[root@7-1 work]# bash one.sh
文件不存在,创建文件
[root@7-1 work]# bash one.sh
文件存在
-rw-r--r--. 1 root root 0 Nov 26 14:49 aa.txt#!/bin/bashcd /tmpfilename=aa.txtif [ -f $filename ]
thenecho "文件存在"ls -l $filename
elseecho "文件不存在,创建文件"touch $filename
fi

2.写脚本判断脚本后边的变量个数是否超过2个 不足提示变量不足,超过提示超过

#!/bin/bashecho "$*"echo "$#"if [ $# -ge 2 ]
thenecho "超过了"
elseecho "变量不足"
fi
~

3.提示用户输入一个变量值 判断输入的值是否为空

#!/bin/bashread -p "请输入一个变量值:" varif [ -z $var ]
thenecho "$var值为空"
elseecho "$var值不为空"
fi

4.从系统中搜索文件man.config是否存在,判断该文件和/root/install.log是否为硬链接

#!/bin/bash
name="man.config"if [ -e $name ]
thenif [ $name -h /root/install.log ]thenecho  "为硬链接文件"elseecho "不为硬链接文件"fi
elseecho "该文件不存在"
fi

5.从系统搜索光盘镜像文件,如果有挂载使用 否则提示下载

#!/bin/bashiso=`find /dev -name cdrom`if [ -z "$iso" ]
thenecho "no"
elsemount -t iso9660 $iso /mnt
fi
~

6.写一个文本文件/tmp/user.txt 内容为
帐号
密码
写一个交互式脚本,让用户输入帐号 密码,判断用户输入帐号密码是否正确,如果正确提示登录成功

#!/bin/bashread  -p "请输入账号: " accountaccount1=`head -1 /tmp/user.txt`
password1=`tail -1 /tmp/user.txt`
if [ $account = $account1 ]
thenecho "账号输入正确"read -p "请输入密码: " passwordif [ $password = $password1 ]thenecho "密码输入正确"elseecho "密码输入错误"fi
elseecho "账号输入错误"
fi

7.写一个判断vsftpd是否正在运行的脚本

#!/bin/bashsystemctl status vsftpd > /dev/null
str=$?
if [  $str -eq 0 ]
thenecho "正在运行"
elseecho "没有运行"
fi

8.写一个判断内存使用是否大于50%的脚本


9.写一个检查系统中登录用户超过5个的脚本

#!/bin/bashnum=`who | wc -l`if [ $num -ge 5 ]
thenecho "超过5个"
elseecho "未超过5个"
fi

10.完善你写过的yum库脚本


11.判断nmap命令是否存在 如果不存在则安装对应的软件包

#!/bin/bashrpm -qa nmap
if [ $? -eq 0 ]
thenecho "未安装"
elseecho "已安装"
fi

12.查看光盘上有哪些软件没有安装,将没有安装的软件包,安装到系统中


13.如何判断一个目录为空目录


14.查看虚拟机的网络内有多少ip地址是活跃的,并且那些ip的ssh服务是开启的?


作业:
1.判断当前用户是否为root 如果为root用户启动ssh服务 如果非root切换用户提示用户启动服务

2.每隔3秒调用自己一次

3.分析下边脚本

a.sh#!/bin/bash
echo $$
./a.sh | ./a.sh &

4.判断自己是否为重复运行脚本,如果为重复运行的脚本则自动退出(同一时间该脚本只有一个实例运行)

5. 循环语法

1. for循环语句

如下脚本

#!/bin/bash
for i in 1 3 5 7
doecho $iecho ok
done 我们还可以将for循环读取的语句写到一个文件里如a.txt
#!/bin/bash
for I in `cat a.txt`
do
echo $i
echo ok
done

添加100个用户

[root@7-1 tmp]# for i in ab{1..100}
> do
> useradd $ab{}^C
[root@7-1 tmp]# for i in {1..100}
> do
> useradd ab${i}
> done
[root@7-1 tmp]# cd /home/
[root@7-1 home]# ls
ab1    ab14  ab2   ab25  ab30  ab36  ab41  ab47  ab52  ab58  ab63  ab69  ab74  ab8   ab85  ab90  ab96  jack   tom
ab10   ab15  ab20  ab26  ab31  ab37  ab42  ab48  ab53  ab59  ab64  ab7   ab75  ab80  ab86  ab91  ab97  jean   zorro
ab100  ab16  ab21  ab27  ab32  ab38  ab43  ab49  ab54  ab6   ab65  ab70  ab76  ab81  ab87  ab92  ab98  jerry
ab11   ab17  ab22  ab28  ab33  ab39  ab44  ab5   ab55  ab60  ab66  ab71  ab77  ab82  ab88  ab93  ab99  king
ab12   ab18  ab23  ab29  ab34  ab4   ab45  ab50  ab56  ab61  ab67  ab72  ab78  ab83  ab89  ab94  ben   robin
ab13   ab19  ab24  ab3   ab35  ab40  ab46  ab51  ab57  ab62  ab68  ab73  ab79  ab84  ab9   ab95  boss  rose
[root@7-1 home]# 2%2

time 命令的使用

real墙上时间,也就是实际消耗时间多少

user用户态消耗的时间.

sys 系统底层消耗的时间(操作硬盘)

计算1-100的累加和(注意初始化值)

#!/bin/bashresult=0for i in {1..100}
doresult=$(($i+$result))doneecho $result

计算1-100奇数的累加和 偶数呢?

#!/bin/bashfor i in {1..100}
do
#jum=`echo "$i%2" | bc`
if [ `echo "$i%2" | bc` -eq 0 ]
thendum=$(($dum+$i))
elsejum=$(($jum+$i))
fi
doneecho "奇数和:$jum"echo "偶数和:$dum"
~

有没有更好的方式

seq 1 2 100 产生1-100个数字 步长为2 脚本就可以变得更简单了

for循环的另一种写法 模拟c语言的写法

for ((i=0;i<10;i++))
doecho $i
donei+=2  i=i+2
i-=2  i=i-2
i*=2 i=i*2
i/=2 i=1/2

数值运算时这种写法更简单 如果文件处理for in的语法更容易写

好了 我们开始完成上边遗留的问题

猜数字给5次机会
又遇到问题.猜对了的情况下还让猜 这时应该跳出脚本 不在继续猜!!!又被打了…

#!/bin/bashnum=$(($RANDOM%100+1))for i in {1..5}
doread -p "输入数字[1~100]:" guessif [ $guess -eq $num ]thenecho "赢了"breakelif [ $guess -gt $num ]thenecho "大了"elseecho "小了"fidone
~

break 和continue 跳出循环
break 跳出循环 脚本继续执行
continue 跳出本次循环,脚本继续执行
exit 退出脚本, 但是exit可以设置脚本返回值

遇到某些条件时这一次的循环跳出continue (如再来一个小游戏:大家说数字1-100 遇到被7整除和含有的7的数就跳出)

#!/bin/bashwhile true
doread -p "input one number: " numres=`echo "$num%7" | bc`res1=`echo "$num/10" | bc`res2=`echo "$num%10" | bc`if [ $res -eq 0 -o $res2 -eq 7 -o $res1 -eq 7 ]thenecho "you lose!"sleep 3break;elsecontinueecho "continue games!"fi
done

2. select循环

select i in ls pwd whoami
do$i
done[root@7-1 ~]# select i in ls pwd whoami
> do
> $i
> done
1) ls
2) pwd
3) whoami
#? 1
\        Desktop    Downloads  initial-setup-ks.cfg  Pictures  Templates  test.sh  work
anaconda-ks.cfg  Documents  game.sh    Music             Public    test   Videos
#? 2
/root
#? 3
root
#?

3. while和until循环

while 后边跟命令 条件为真值时循环

until 后边跟命令 条件为假值时循环

更多用while做死循环

语法

while cmd
do
list
done如 true为真值 0
while true
dosleepecho ok
done:空指令
死循环
while true
do:
done不会死机 cpu发现为死循环 降低该进程优先级
#!/bin/bash#14.sh
x=0
while [ $x -lt 10 ]
do
echo $x
x=`expr $x + 1`
done#!/bin/bash
#15.sh
sum=0
while [ $sum -lt 10 ]
do
sum=`expr $sum + 1`
useradd user$sum
echo "123456" | passwd --stdin user$sum
done

4. until语法

until cmd
do
list
done#!/bin/bash
#16.sh
x=1
until [ $x -ge 10 ]
do
echo $x
x=`expr $x + 1`
done
相当于
x=1
while [ ! $x -ge 10 ]
do
echo $x
x=`expr $x + 1`
done当用户robin 登录系统时 提示robin登录系统,记录用户信息(名字 时间  tty)

6. case分支语法及函数

1. case语法结构

case word in
pattern1)
list1
;;
pattern2)
list2
;;
... ...
patternN)
listN
;;
*)
list*
;;
esac

超市卖水果

#!/bin/bash
read –p “请输入你要查询的商品: ”var
case $var in
apple)echo "apple 1.4元每斤"
;;
orange)echo "orage 1.5元每斤"
;;
banana)echo "banana 1.6元每斤"
::
esac

/etc/init.d/sshd
用法:/etc/init.d/sshd {start|stop|restart|reload|condrestart|status}
服务用法的实现

#!/bin/bash
case $1 in
start)echo "start"
;;
stop)echo "stop"
;;
restart|reload)echo "restart"
;;
*)echo "Usage: $0 start|stop|restart"
esca

在这个基础上我们来实现一个小服务的脚本
nc 命令可以监听段口
nc –l 9999
好了,我们可以启动一个小服务了

#!/bin/bash
case $1 in
start)echo "start"nc –l 9999
;;
stop)echo "stop"pkill nc
;;
restart|reload)echo "restart"pkill ncnc –l 9999
;;
*)echo "Usage: $0 start|stop|restart"
esca

pidof取一个进程的pid

完善一些这个模拟服务的脚本

#!/bin/bash
start(){if [ -f /tmp/nc.lock ]thenecho "nc is runing"elseecho "start"nc -l 9999 &touch /tmp/nc.lockfi
}
stop(){if [ ! -f /tmp/nc.lock ]thenecho "nc is not runing"elseecho "stop"PID=$(pidof nc)kill -9 $PIDrm -rf /tmp/nc.lockfi
}
case $1 in
start)start
;;
stop)stop
;;
restart)stopsleep 1start
;;
*)echo "Usage:$0 start|stop|restart"
esac

函数也可以让我们死机 如下

Shell-基础部分相关推荐

  1. day23:shell基础介绍 alias及重定向

    2019独角兽企业重金招聘Python工程师标准>>> 1.shell基础介绍: shell是一个命令解释器,用于用户与机器的交互: 也支持特定的语法(逻辑判断,循环): 每个用户都 ...

  2. shell基础(四)uniq和tee

    shell基础(四)uniq和tee uniq用来去重复的行,最常用的选项只有一个,即-c count 统计重复的行数,并把重复的数量写在前面. 注意:使用前提是需要先给文件排序,否则不管用. #vi ...

  3. linux shell 基础 使用日志与心得

    linux shell 基础 使用日志与心得 1.#!/bin/bash 第一行就出现 #!/bin/bash是指此脚本使用/bin/bash来解释执行. 其中,#!是一个特殊的表示符,其后,跟着解释 ...

  4. 一、Linux Shell基础

    1.1.shell基础 Bash 是一个与Bourne Shell兼容的.执行从标准输入设备文件读取的命令的语言解释器.Bash是Bournae-Again Shell的缩写.Bash与原来的Unix ...

  5. Xamarin.Forms Shell基础教程(1)

    Xamarin.Forms Shell基础教程(1) 什么是Xamarin.Forms Shell Shell是Visual Studio为Xamarin Forms提供的解决方案模版.本质上,She ...

  6. linux shell概述,Linux学习 -- Shell基础 -- 概述

    Shell是什么? 命令解释器 编程语言 Linux支持的Shell类型 cat /etc/shells 主要学习 bash 脚本执行方式 echo echo -e 单引号 -- 原始字符串  双引号 ...

  7. Shell基础-环境变量配置文件

    Shell基础-环境变量配置文件 Shell基础-环境变量配置文件 source 配置文件 或者 . 配置文件: 把环境变量写入配置文件后,需要用户重新登陆才能生效,而是用source命令,则能直接生 ...

  8. shell基础二十篇 一些笔记

    shell基础二十篇 转自 http://bbs.chinaunix.net/thread-452942-1-1.html 研讨:Bash 内建命令 read (read命令更具体的说明见博客收藏的一 ...

  9. shell基础二:查找技巧,find及xargs的使用

    2019独角兽企业重金招聘Python工程师标准>>> 使用find时,只要把想要的操作写在一个文件里,就可以用exec来配合find查找,很方便的 (在有些操作系统中只允许- e ...

  10. linux+管道+分段,Linux中shell基础、重定向、管道符、环境变量

    原标题:Linux中shell基础.重定向.管道符.环境变量 1.什么是shell Shell是系统的用户界面,提供了用户与内核进行交互操作的一种接口(命令解释器).它接收用户输入的命令并把它送入内核 ...

最新文章

  1. java file_Java IO: File
  2. sqlite 0转换为bit_DA转换实例
  3. -webkit-overflow-scrolling:touch
  4. 5G NR — 毫米波
  5. ue4 怎么修改骨骼动画_UE4换装系统(合并骨骼模型)
  6. mqtt调试助手_物联网入门,如何使用MQTT协议,连接Tlink物联网平台
  7. web前端技巧-ES6新特性与重点知识汇总(三)
  8. 连接虚拟机mysql无法访问_连接虚拟机mysql无法访问,报错编号1130的解决方法
  9. gpu处理信号_GPU中的并行运算,加速你的Matlab程序
  10. mysql8.0版本的服务器名称_云服务器Mysql安装配置
  11. ocx控件 postmessage消息会消失_通过HackerOne漏洞报告学习PostMessage漏洞实战场景中的利用与绕过...
  12. Swagger2-注解说明
  13. 为什么有那么多人选择Python,真的有那么好吗?
  14. Android基础入门
  15. 《Head First Android》读后感,电子书PDF下载
  16. 中国人工智能AI人才需求现状
  17. [Tableau] 销售团队绩效分析与相关策略指导
  18. 停课不停学的网络教学方案
  19. 图灵机跟现实电子计算机哪个计算能力强,计算机不是只会“计算”,图灵机也不是一台“机器”|AI那厮...
  20. css select默认选中字体颜色,通过js修改input、select默认字体颜色

热门文章

  1. 姓名拆分为姓氏和名字的方法
  2. 注册时要求获取手机短信码的实现(java)
  3. 华为机试C语言-最远足迹
  4. 机器学习实战决策树画图理解
  5. 地铁AFC付出体式格局近况及移动付出安好性探究
  6. 微信 昵称带 表情存入mysql数据库
  7. 制作标准1寸和2寸照片方法
  8. 沙漠下新雨,树木爆翠绿,没有放弃与更新,就不成其智慧。我们不必时刻刷新微博和朋友圈,比起这些,刷新自我更加重要。我们并不需要生活在别处,不需要流于表面,我们需要时常更新生命。
  9. python实现翻转金字塔图案
  10. WX Live game