目录
一、shell脚本概述
二、编写第一个shell脚本
三、重定向
四、管道符号
这两天想起来大学的快乐时光,感觉时间过的很快,在之前公司实习的日子好像才过去不久,想到当时自己自学java,那叫个苦逼,而且现在想起来,当时看完一篇也就看完了,完全没有做笔记,导致后面遇到同样的问题只能再辗转反侧去网上找答案和解决方法。刚好利用这次机会记录一下shell脚本里平时经常用的一些东西或者遇到的问题,顺便和大家一起学习。
一、shell脚本概述
shell 作为一种包含了变量、语句、循环等的代码,它并不是一个编程语言,但它提供了编程的环境,用来编写脚本和自动化任务。它是操作系统的命令解释器,它提供了一个用户与操作系统交互的界面。将输入结果变成计算机能识别的二进制程序,同时又把计算机生成的结果返回给我们。
在Linux系统中的Shell是一个特殊的应用程序,它介于操作系统内核与用户之间,有很多种,使用不同的 Shell 时,其内部指令、命令行提示符等方面会存在一些区别。
我们可以通过 查看过 /etc/shells 文件可以了解当前系统所支持的 Shell 脚本种类
/bin/sh
: Bourne shell,是 Unix 的标准命令行 shell
/bin/bash
: Bourne Again shell,是 Bash shell 的路径
/sbin/nologin
: 用于系统帐户,禁止登录的 shell
/usr/bin/sh
: 在某些系统中用作默认的 Bourne shell 的路径
/usr/bin/bash
: 在某些系统中用作默认的 Bash shell 的路径
/usr/sbin/nologin
: 在某些系统中用于系统帐户的禁止登录 shell
路径知道了,那么怎样执行shell脚本呢?道理很简单,其实就是将原来 linux 系统的命令或语句放在一个文件中,然后通过这个程序文件去执行,有点像别名,别名一次只能执行一条语句,脚本编写完之后可以执行数条;又有点像计划任务,到什么时间自动执行什么任务,但shell脚本的功能比计划任务和别名多太多了。我们可以用自动化脚本完成软件的安装部署,进行系统的管理,分析处理等,只要是需要大量复杂、重复性的工作时,都可以编写一个脚本,一劳永逸。
二、编写第一个shell脚本
基本概况介绍完了,差不多该讲如何编写了,或者说是编写规范之类的。当然,前提是Linux基础命令得熟悉,不然不知道什么时候干什么。
先创建一个 .sh 文件
然后,第一行得声明默认的代码解释器,就是以下代码都是通过什么来执行的。我们现在接触到的大多数脚本都是以这个开头
#!/bin/bash
就类似于c语言里的 #<stdio.h>
只是有点像,并没有说两者有什么联系或者作用一样。
和java不一样,shell里的注释不是/或者/*,而是#,假如是/,可以想象,那不乱套了,倒底是根/,还是注释,机器的转爆了。
声明完了之后,就到了正文部分。
一切编程都是从 helloworld 开始,咱们也不例外
我们直接 echo “hello world”
然后保存退出,接着得给文件赋权,给它一个执行权限。
chmod +x [刚才创建的文件]
大致步骤如下,1.sh 内的代码就是
#!/bin/bash
echo “hello world”
好了,shell脚本“问世”了
大家可以注意到,执行的时候是输入了路径的,显然不输入命令肯定是执行不了的,就像你创建了一个普通的 1.txt文件,你直接输入文件名,那肯定啥反应也没有的。
然后还有一点就是,文件在执行前进行了赋权,那么,不赋权可以执行脚本吗?其实也是可以的
我们来把文件的执行权限去掉
不赋权也能执行的方法就是
如果离开opt目录,那么执行的时候要加上绝对路径
以上三种方法都可以,还有一种比较复杂的方法需要用到管道符号和重定向。
sh < first.sh 或者 cat first.sh |sh(bash)
既然说到重定向和管道符号了,就顺便说一下。
三、重定向
重定向是将命令的输入或输出从默认位置(通常是终端)重定向到其他地方(如文件或另一个命令),输入输出分为:
标准输入(STDIN):默认的设备是键盘,设备文件/dev/stdin,文件编号为 0,命令将从标准输入文件中读取在执行过程中需要的输入数据。
标准输出(STDOUT):默认的设备是显示器,设备文件/dev/stdout,文件编号为 1,命令将执行后的输出结果发送到标准输出文件。
标准错误(STDERR):默认的设备是显示器,设备文件/dev/stderr 文件编号为 2,命令将执行期间的各种错误信息发送到标准错误文件。
简单来说就是,标准输入是从该设备接收用户输入的数据;标准输出是通过该设备向用户输出数据;标准错误是通过该设备报告执行出错信息。
那么还有一点疑问,为什么012三个数字要被着重强调呢?
我们也知道,echo “内容” > [文件] 可以将指定的内容写入文件里,如果文件里本来有内容的话,就会覆盖。其实这里 > 前面有个1,1是默认的没有显示。
那么 1> 真正的含义是,重定向输出,将输出结果保存到指定的文件(覆盖原有内容)
假如我不想要覆盖,只想在后面加一段,那就是 >> 或者1>> 也行,一个意思
被顺利地追加上去了
然后 0 所对应的就是重定向输入
2 对应的就是错误输出,将错误信息保存到指定的文件 单> 和 双>> 效果和重定向输出一样。
什么叫错误输出呢?举个例子,我们opt目录下没有3.txt这个文件,现在我们要将 rm -rf 3.txt 这个命令的执行结果放到2.txt中,此时,2.txt里就会记录了 删除命令的报错内容
可以看到,2.txt里有我之前ls 3.txt 的报错信息,还有删除 3.txt 文件的报错信息,很好理解吧?
那假如,我既要又要呢?
对的也要错的也要
那我们就需要用 混合输出 &> 这样,无论正确还是错误的信息,都会被写入
四、管道符号
管道符号我们之前就有所接触了,位于管道符号 “|” 左侧的命令输出的结果,将作为右侧命令的输入(处理对象),同一行命令中可以使用多个管道。这个之前讲过,这里就不过多赘述了。
主要是有一个新的东西,就是筛选列,我们都知道grep是筛选特定的行,awk 可以进行特定的列筛选
我可以用ps -aux 举例 ,我们都知道第一列 是执行这个进程的用户,那么我们现在要显示第一列所有内容
ps -aux | awk '{print $1}'
只有第一列被显示出来了
接下来我们来点复杂的,加入两个管道符号,查看以/结尾的行,第6列
初识shell脚本就讲到这里,之后的我会整理好再进行补充,然后发出来和大家交流。