玩转Linux Shell编程(一)

216 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第9天,点击查看活动详情

前言

本系列目录

  1. Linux Shell和基本指令
  2. Bash shell语法
  3. 正则表达式
  4. 文本处理之grep
  5. 文本处理之sed
  6. 文本处理之awk
  7. Text GUI编程
  8. Tomcat启动脚本分析
  9. gradlew脚本分析

在和Linux打交道以及在Linux下开发软件时候,离不开shell,它为用户提供接口,使我们可以使用操作系统提供的服务,我们可以向shell提供一些命令,然后shell会将它们转换为内核可理解的形式并完成相应的任务,所以本系列分为9章,前7章介绍shell的基本使用,后两章介绍两个经常用的shell脚本,tomcat启动脚本和gradlew脚本。

这里假设你已经有一些linux基础,所以我们直接进入主题。

如果你打开tomcat的启动脚本或者gradle脚本时候,最顶部都是一些#!/bin/sh#!/bin/bash之类的,这是告诉这个脚本应该由哪个解释器执行,除了这两种,还有Python时,可以指定#!usr/bin/python,这样就可写一段python脚本。

#!/bin/sh#!/bin/bash是两个不同的shell,最早的是#!/bin/sh,被称为Bourne shell,他属于Linux系统中GNU项目的一部分,后来经过发展,才出现了#!/bin/bash,所以他的功能更强,速度更快,目前Linux发行版都默认配置了他。 我们在例子中都会使用#!/bin/bash

可以通过下面命令来获取Linux常用的shell类型。

cat /etc/shells 

# /etc/shells: valid login shells
/bin/sh
/bin/bash
/usr/bin/bash
/bin/rbash
/usr/bin/rbash
/bin/dash
/usr/bin/dash

并且在终端执行echo $SHELL,默认大部分都是/bin/bash

root@iZ2ze11z3fucyu4974yrxsZ:~# echo $SHELL
/bin/bash

Hello Shell

下面我们编写一段hello shell程序。

首先创建一个sh文件,并设置具有可执行权限。

touch hello.sh
chmod 777 hello.sh

编辑内容

#!/bin/bash
echo "hello shell "

执行。

./hello.sh 
hello shell 

以上使用到了一个echo指令,用来回显,将后面的字符或者变量打印出来,如果你经常运行一些shell脚本,可以发现有的输出是有颜色的,这可以使用ansi 转义码来完成,如下。

echo -e "下一个字符是红颜色 \e[1;31mRed"

在这里,'\e'表示转义序列的开始,'[1'表示为粗体,31是红色的颜色代码,'m'表示转义序列的结束,当然还可以设置背景颜色,这里就不介绍了。

所以说,在编写shell的前提,我们需要熟练掌握Linux常用命令,才能完成预想的结果。

Linux常用命令

文件和目录操作

  1. pwd:显示当前工作目录

  2. ls:列举文件和文件夹

  3. cd:切换当前工作目录

    cd时候,cd ~或者直接cd表示进入登录用户的个人目录,cd -表示回到刚才目录。

  4. less、more、cat浏览文本文件

  5. file:文件类型

  6. touch:创建文件、修改、更改时间戳

  7. mkdir:创建文件夹

  8. cp:复制文件和目录

  9. mv:移动/重命名文件和目录

  10. rmdir:删除目录

  11. rm:删除文件和目录

以上是一些基础的命令,但由于参数众多,玩法很多样,网上有大量可参考,如ls显示当前目录中所有文件,但他有30多个参数供我们选择,如加-l参数进行文件的详细信息显示,加--time-style参数指定时间显示格式,如ls -l --time-style=long-iso这样我们就可以更直观的显示文件的时间。

这里就不全介绍了,下面是这几个命令的一个实例。

#!/bin/bash

echo "当前工作目录"
pwd

echo "切换目录"
mkdir test
cd test
pwd

touch new.txt
ls

运行后输出结果如下

$ ./hello.sh 
当前工作目录
/home/HouXinLin/project/shell
切换目录
/home/HouXinLin/project/shell/test
new.txt

IO重定向和管道

一般情况下都在屏幕上显示输出结果,这被称为标准输出,文件描述符是1,但可以利用重定向将结果输出到文件中,做法就是使用>这个大于号,如ls -l > ls.txt作用把ls -l的输出结果写入到当前目录下的ls.txt文件中。

但使用>时会删除原有的数据,如果需要将结果追加到原文件后面,可以使用两个大于号>>

还有标准错误输出,文件描述符为2,有一种写法是2>&1,意思是将标准错误输出也传递到标准输出的位置,也可以将标准输出重定向到/dev/null上,如cat a.txt >/dev/null,他是一个空设备,一种特殊类型的虚拟设备,每个Linux系统中都存在,这个设备的目的是扔掉传递给它的任何内容。

在这里,如a.txt存在,则不会有输出,但如果不存在,则输出错误,可以加2>&1连同错误输出也重定向到/dev/null上,这样不会显示任何信息。

cat a.txt >/dev/null 2>&1

还有就是管道技术,作用是将前一个命令的结果作为下一个命令的输入,我们通常使用下面命令来查看某个端口的状态.

netstat -anp |grep 80

这条命令是显示关于80端口的信息,中间这个|则表示管道,来连接一个标准输出成为另一个命令的标准输入,而grep也被称为过滤器程序,他会以行为单位,搜索指定字符模式的行并输出,还有类似sort进行排序等。

文件权限

windows下我们很少使用权限,至少我用的不多,要写个bat脚本,写完双击直接运行,程序要管理员权限,直接右击以管理员方式打开,而在linux不同了,写完脚本还要手动赋给可执行权限。

linux下文件权限由这三个命令组成。

  1. chmod: 修改文件/目录访问权限

  2. chown: 修改文件/目录所有者

  3. chgrp: 修改文件/目录的组所有者。

查看文件权限信息同样可以使用ls -l命令,如下。

 ls -l
 
-rwxrwxrwx 1 hxl hxl 35 68 12:26 hello.sh

在这里,第一个-表示这是一个文件,如果是目录的话,则这里是d。

linux中的权限使用下面信息表示

r = 读取权限
w = 写入权限
x = 执行权限
 = 无权限

而通过ls -l命令查看后出现的一长串rwxrwxrwx需要每三个一组看。

image.png

从上所述,hello.sh这个文件是最开放的。

而chmod用来修改权限,参数如下。

chmod [permission] [file_name]

权限有两种方式写

  1. 使用符号(字母)
  2. 使用八进制表示法

如要取消用户、组、所有人的可执行权限使用第一种方式如下。

chmod u=rw-,g=rw-,o=rw- hello.sh

而要用八进制表示需要先了解对应值。

读取 (r) = 4.
写入 (w) = 2.
执行 (x) = 1.

所以当让一个文件具有如可读写可执行权限时,值是7(4+2+1),如下。

chmod 764 hello.sh

这样表示用户具有所有权限,组具有读写权限,所有人具有读取权限。

chown可以更改文件所有者,但只有超级用户才能使用chown命令,如现在有一个su.txt,需要改为testUser为所有者。

 chown testUser su.txt 
 ls -l
 
-rwxrwx--- 1 testUser root  0 6月   8 15:33 su.txt

chgrp则用来更改组,Linux中的所有文件都属于一个所有者和一个组,组中可以有多个用户,用来统一管理组内用户。

addgroup test-group
chgrp test-group su.txt
-rwxrwx--- 1 testUser test-group  0 68 15:33 su.txt

作业控制

一般要在后台执行的程序,需要在最后加入 & 在后台运行,如现在有下面这样一个脚本,作用是每隔一秒将num追加到log文件中,并num自增1。.

#!/bin/bash
num=0

while true
do
	echo "$num" >>log.txt
	sleep 1
	let num+=1
done

如果我们只./xx.sh运行,那么当前终端就没办法做其他事,只需要在后面加入&,即可让这个任务在后台运行,但当前终端关闭后,这个任务也会死亡,如果需要真正在后台,需要在前面加入nohup。

当任务在后台运行后,可以使用jobs命令显示当前在后台执行的任务,但只对当前终端有效,并且可以使用bg、fg进行前后台切换,如下。

jobs
[1]+  已停止               ./hello.sh
[2]-  运行中               ./hello.sh &

将2号切换到前台,使用下面指令

bg %1

当一个任务在执行时候,可以按下Ctrl+z,系统将会暂停这个进程,但不是杀死,这时候可以通过bg命令放入后台执行,或fg命令切换到前台,bg和fg都需要一个id,这个id就可以通过job查看。

也可以使用kill %1终止指定编号的任务.

系统管理指令

这部分指令太多了,大家可以参考一些网上的

一行多条指令

一行可以写多条,中间使用;&&||分割,区别如下。

  1. ;

    即使第一条执行失败,第二条也会执行,如使用ct;touch a.txt这条命令,因为ct不是Linux命令,不存在,会报错,但第二条的创建文件还是会执行。

  2. &&

    当第一条指令执行失败后,第二条不会执行,还是使用上面例子ct& & touch a.txt,这时不会创建文件

  3. ||

    只有当第一条命令执行失败时候,才会执行下一条命令,如ls || touch b.txt不会新建b.txt,而ct || touch b.txt会新建。

    当然可以一行上连续使用多次。

重复执行命令

要重复执行2次同一条命令,可以使用!#,如date ;!#会执行两次date命令,中间可以使用如sleep进行等待,如date;sleep 1;!#