我用 LinuxLinux程序员

十分钟入门shell脚本

2019-01-13  本文已影响2人  ca202e4d3a56

在正式开始前,我们可以思考一个问题,学习一门技术难吗?不少人的答案可能是很难。

来看一个案例,也可以说是两个。

2017年苹果WWDC大会上,有两名开发者令世界瞩目。一个是已经82岁,来自日本的老太太,若宫正子;另一个是年仅10岁,来自澳大利亚的小朋友,Yuma。前者60岁时才接触电脑,81岁时用上Mac系统,然后花了半年时间开发出了自己的app;后者从6岁开始设计网站,随后四年为苹果商店贡献了五个app。有意思的是,两个人都有自己的编程课堂,老太太在自己家教老人电脑知识,小Yuma建了一个Youtube频道,叫 Anyone Can Code(人人皆可编程),主要教小孩编程。

若宫正子 Yuma

或许有人想说,他们不过是天赋好罢了。但我只想说,这种想法不过是不敢跳出舒适区,为自己的懒惰和无能找借口罢了。

如今,各种底层技术已经经过层层封装,可以说,只要你有想法,编程甚至能够像搭积木一样简单。

首先,你有什么需求,你的这个需求可以被什么技术解决,了解它的基本概念,然后把它变成生活的一部分,想方设法它。遇到问题了怎么办?把大问题拆分成小问题,找搜索引擎解答。

记住一点:你没必要学习某技术的所有知识,了解基本概念,基本原理,就可以用它了。

有人又会说了,我没啥需求怎么办?李敖曾说过:“作家不能等有了灵感才写作,一如妓女不能等有了性欲才接客。”

下面我们来学习shell脚本吧。主要面向linux初学者以及对linux感兴趣的人。请自行准备linux系统或Mac系统。

什么是Linux内核?

我们大多知道操作系统,但少有人知道内核,像CenOS,Redhat,Ubuntu等,这是操作系统,内核是Linux kernel,它是操作系统的心脏,是操作系统的大脑,去掉它,操作系统将不复存在,你的电脑也会成为破铜烂铁。

不用过于深究,你可以简单地将内核看做电脑的大管家,它的小弟们与它一起构成了操作系统,共同管理计算机资源。

什么是shell?

我们知道,计算机实际只懂0和1(二进制),我们与外国人沟通需要靠翻译,那么同计算机沟通当然也需要一个翻译,shell就是这个翻译。另外,你以为你是同计算机对话,其实不然,你实际上是同内核对话,你在电脑上看到的内存啊,磁盘啊,CPU等都是虚拟出来的,你的任何操作,最终都是由内核真正在计算机硬件上执行。

总结下shell定义:

什么是bash shell?

shell的版本有很多像什么sh、bash、csh、ksh等,其中bash是Linux世界使用最广泛的shell,也是很多Linux发行版的默认shell。

获取当前系统可用shell

[root@localhost ~]# cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin

查看当前使用的shell

[root@localhost ~]# echo $SHELL
/bin/bash

什么是CLI和GUI?

尝试执行几个基本命令

[root@localhost ~]# echo "hello,linux"
hello,linux
[root@localhost ~]# date
Sat Jan 12 23:48:13 CST 2019

什么是标准输入、标准输出和标准错误输出?

我们执行一条shell命令,就会打开这三个文件,你可以理解为三条管道,标准输入与键盘相连,标准输出和标准错误输出都默认与屏幕相连。没有特别指明的情况下,我们通过键盘输入的内容通过“标准输入”这条管道“流入”至相应的命令,命令的执行结果又会通过“标准输出”或“标准错误输出”这条管道“流出”至屏幕,展现在我们面前。

比如输入cat test.txt,cat这个命令作用是从命令行给出的文本中读取数据并将数据送到标准输出。

如果test.txt中有内容,那么标准输入就不是键盘了,而是该文件,文件内容通过“标准输入”这个“管道”流向cat命令,cat命令读取其内容,然后将内容“流出”至标准输出,即屏幕上。

# 将"hello"添加到test.txt这个文件中,如果不存在就创建
[root@localhost ~]# echo "hello" > test.txt   
# 输出test.txt文件内容
[root@localhost ~]# cat test.txt
hello    #标准输出

假如test.txt不存在,那么就会报错,错误信息通过“标准错误输出”这条管道“流出”至屏幕上。

[root@localhost ~]# cat test.txt
cat: test.txt: No such file or directory    #标准错误输出

假如cat命令后面没有参数,那么其标准输入便是键盘了,终端就会等待我们输入,cat获取标准输入,通过“标准输出”这条管道输出到屏幕上。

[root@localhost ~]# cat
hello   # 标准输入
hello   # 标准输出

什么是重定向?

比如一条命令cat test.txt,它会把test.txt这个文件的内容输出到屏幕上,但我不想输出到屏幕上,我想保存到一个文件里,就可以用”标准输出重定向“符号>将其重定向到某个文件cat test.txt > temp.txt,这样屏幕上就没有输出,也就改变了标准输出的流出方向,故而称之为”重定向“。

什么是管道?

前面我们了解到,命令的标准输出默认是屏幕,假如该命令的标准输出我们想再利用怎么办?那就需要利用管道了。强调一下,标准输出是指命令执行成功后的输出。

举个例子:

[root@localhost ~]# echo “zhangsan” | useradd
# 这条命令的意思是输出”zhangsan“,并利用useradd命令添加其为linux普通用户
# ”zhangsan“为管道前的标准输出,管道将其变成后面useradd命令的标准输入

注意事项:

[root@localhost ~]# echo "/etc"| xargs ls
# 没有xargs的话,这里的ls只能列举当前目录的内容,而非/etc这个目录

什么是shell脚本?

前面说过,shell是一个命令语言解释器。另外,shell本身也是一个程序,有自己的命令,像什么ls、cd、pwd等都是其内置命令,还有一些其他命令,都是别人为linux添加的基本命令。我们知道,编程时通过各种库调用来实现功能,而shell没有库,他通过调用各种命令来实现相应功能。

我们通过输入各种命令与shell交互,但有时我们不想手动输入各种命令,我们想把命令存在一个文件中,然后让shell执行该文件中的命令,于是就有了shell脚本。

所谓的shell脚本其实就是一个包含一系列shell命令的文本,目的是减少重复工作,实现自动化。

shell脚本基本组件

shell脚本是由各种shell命令组成,但绝对不是简单的命令堆积,它像其他编程语言一样,有自己的基本组件。

如何快速编写一个脚本?

脚本组成

一个完整的脚本有三部分组成:脚本声明、注释以及可执行语句。

一个批量ping ip脚本

说了这么多,让我们开始写一个脚本吧,先说一个命令,检测网络通不通,需要用到ping命令,我们想批量检测某一个网段的主机是否网络通畅,那就需要用到for循环。

#linux中默认编辑器通常是vi或vim,该文本编辑器分为三种模式
#默认是普通模式(无法输入内容,但可以通过相应命令操作文本),普通模式下按i表示进入插入模式(可以插入内容了)
#按:表示进入命令行模式(批量操作文本),在插入模式或命令行模式下按ESC进入普通模式。输入ZZ或:wq退出vim编辑器
[root@localhost ~]# vim ping.sh
 #默认进入普通模式,先按i开始编写脚本,下面是脚本完整内容
 
 #!/bin/bash
 NET=192.168.1    #声明一个变量并赋值
 for i in {1..254}    #后面的{1..254}表示循环范围从1-254,如果你就是想测试下,这里就改成{1..10}吧
 do
 IP=$NET.$i    #字符拼接并赋值给IP这个变量
 ping -c 3 $IP &> /dev/null    
 #-c指明发包次数,&> /dev/null表示无论正确输出还是错误输出统统丢弃
 #$?表示上条命令的执行结果,0表示成功,非0表示失败
 #-eq代表”是否等于“,[]是条件测试语法,测试条件左右必须各留至少一个空格
 if [ $? -eq 0 ];then    
     echo "$IP is up" 
 else 
     echo "$IP is down"
 fi
 done
 # 编写完毕,按ECS进入普通模式,然后输入:wq退出vim编辑器

脚本执行

执行脚本主要有三种方法:

第一种方法,如果你没有shebang语句(即第一行声明解释器),可能会报错;第二种方法,你可以不声明解释器类型,因为你是直接用解释器来执行的,也可以不赋予执行权限;第三种方法,你是在当前shell环境来执行的,前两种实际上都是在子shell中执行,执行完毕才退回到当前shell。

基本上用哪种方法都行,看你心情。

# 假如你想把执行结果保存到一个文件,也就会利用输出重定向
# 但同时你又想输出其结果到屏幕上,那就会用到tee命令了
[root@localhost ~]# bash ping.sh | tee out.txt
192.168.1.1 is up
192.168.1.2 is down
...

#现在你想知道有多少个ip是通的,这就用到涉及文本过滤命令grep以及统计命令wc
[root@localhost ~]# grep "up" out.txt | wc -l
   3

最后补充一点,同window不同,linux世界,文件后缀没有任何意义,加后缀名只是方便人类自己查看。

学习一门新技术,最痛苦的过程只是前两小时,熬过了这两小时,后面就会越走越顺。

上一篇 下一篇

猜你喜欢

热点阅读