shell的使用方法

shell使用方法

学习技巧

  • 认真听课
  • 给所有脚本添加上注释
  • 用写好的脚本进行修改,达到修改后仍可正常执行的效果
  • 根据自己的需求整理思路并创造完整的脚本

什么是 shell

Shell 编程跟 JavaScript、php 编程一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了。
Linux 的 Shell 种类众多,常见的有:

  • Bourne Shell(/usr/bin/sh或/bin/sh)
  • Bourne Again Shell(/bin/bash)
  • C Shell(/usr/bin/csh)
  • K Shell(/usr/bin/ksh)
  • Shell for Root(/sbin/sh)
    ……

shell 在 linux 中称为 linux壳,在壳中间是 linux 的系统内核

简单的来说,shell 是帮助用户与系统内核之间进行沟通的桥梁

举个例子:

我们现在在一个互联网公司中,现在老板让我们和一个国外的客户商谈一个项目,然而呢,我们英语不好,可以说是菜的一批…
这个时候我们就需要花重金聘请一位翻译来为我们进行信息的传达,而这个翻译的身份,就相当于我们现在所说的 shell,懂了吧?

ok

Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。
Shell 既是一种命令语言,又是一种程序设计语言。
Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问 操作系统内核 的服务。

shell分两大类:

1. 图形界面shell(Graphical User Interface shell 即 GUI shell)

应用最为广泛的 Windows Explorer (微软的windows系列操作系统)

1. 命令行式shell(Command Line Interface shell ,即CLI shell)

bash / sh / ksh / csh / zsh(Unix/linux 系统)
MS-DOS系统
cmd.exe/ 命令提示字符(Windows NT 系统)

传统意义上的shell指的是命令行式的shell,以后如果不特别注明,shell是指命令行式的shell。

Shell基本上是一个命令解释器,类似于DOS下的command。它接收用户命令(如ls等),然后调用相应的应用程序。较为通用的shell有标准的Bourne shell和 C shell

交互式 shell 与 非交互式 shell

1. 交互式模式就是shell等待你的输入,并且执行你提交的命令。这种模式被称作交互式是因为shell与用户进行交互。这种模式也是大多数用户非常熟悉的:登录、执行一些命令、签退。当你签退后,shell也终止了。

2. shell也可以运行在另外一种模式:非交互式模式。在这种模式下,shell不与你进行交互,而是读取存放在文件中的命令,并且执行它们。当它读到文件的结尾,shell也就终止了

Shell 程序本身的功能是很弱的,比如文件操作、输入输出、进程管理等都得依赖内核。我们运行一个命令,大部分情况下 Shell 都会去调用内核暴露出来的接口,这就是在使用内核,只是这个过程被 Shell 隐藏了起来,它自己在背后默默进行,我们看不到而已。

接口其实就是一个一个的函数,使用内核就是调用这些函数。

如下图,是我从网上摘下来的图片

shell_introduction

Shell Script

Shell Script,顾名思义,名为 shell 脚本

查了查网络上的资料
找到了鸟哥🐦对于 shell 脚本的定义

鸟哥的专业解释:
shell脚本是利用shell的功能所写的一个「程序」。这个程序是使用纯文本文件,将一些shell的语法与命令(包括外部命令)写在里面,搭配正则表达式、管道命令与数据流重定向等功能,以达到我们所想要的处理目的

嗯 , 差不多就是这个意思

那么为什么会产生 shell 脚本呢?

这样,我举个例子吧

假设我现在是一名小公司的运维人员,项目经理下达一项命令,每周日的凌晨 3 点备份公司的某某数据库的数据,并且将备份的数据库的日志文件拷贝一份给老板,于是乎,我们按部就班的每周日都要去一个一个去输入相应的命令
这样效率非常低…
一者,时间上来讲,我们总不能一直那么大晚上的去工作
二者,每周都是相同的命令,做起来非常浪费时间,没有意义
那么,有人就想,能不能把命令都集中到一起写入到文件中,使用时直接执行那个文件不就好了吗?
于是,shell 脚本经过漫长的演变,成为了现在的模样.

第一个脚本:Hello World

vim test.sh

1
2
3
#!/bin/bash

echo "hello world"

bash test.sh

执行方式

  • ./ (需要使用 chmod +x hello.sh 给文件执行权限)
  • bash

命令:echo

  • -e : 输出特殊字符的输出

示例:

1
echo -e "\\"
  • -n : 输出指定内容后不换行
  • \a : 输出警告声音
  • \n : 换行
  • \t : 插入tab
  • \ : 插入 \ 符号
  • \e[nm *\e[om : 用来指定 * 输出时的颜色格式

示例:

1
echo -e "\e[31mhello world\e[0m"

wxr权限的功能

文件下:

  • W:文件可写
  • X:文件可执行
  • R:文件可读

目录下:

  • W: 可以建立新目录/删除已存在目录/修改已存在的目录

  • X: 具有执行的权限,简单地说,就是可以将该目录转换成家目录的能力,比如cd 命令。注意,x权限对于目录是极其重要的,如果没有该目录,表示你不能切换到该目录,更不能对其子目录或者文件进行操作,即使你有“r/w”权限。

  • R: 可查询此目录下文件名数据,比如ls命令


小贴士:

shell: 帮助用户和内核之间进行沟通的桥梁(接口:API)

RedHad/CentOS/Ubuntu使用的都是Linux内核

所有开头带的文件都是隐藏文件


命令history

历史命令配置文件只会保存本次登陆之前的历史命令

选项:

  • -w: 把缓存中的历史命令同步到 .bash_history 中
  • -c: 仅清空缓存中的历史命令(不清空配置文件 .bash_history 的内容)

history历史命令的快速调用:

  • 上下光标
  • !n,重复执行历史命令中的第n个命令
  • !!,执行上一个命令
  • ! + 字符,执行最近一次以该字符开头的历史命令

起别名

配置文件:
.bashrc(单用户生效)
/etc/bashrc(所有用户生效)

1
source /etc/bashrc	//让配置文件中的配置立即生效

格式:alias 别名 = '命令[选项]'(不能使用已经存在的命令作为别名)

\ 称为转义符:将该符号后的字符不产生其特殊作用
示例:\rm aaa

ctrl

  • ctrl + l,快速清屏
  • ctrl + c,停止运行
  • ctrl + d,(关闭/退出)登录/窗口

重定向

wc: wordcount

输入重定向:<(覆盖式写入),此重定向有一定的风险

命令:wc < filename

示例:

1
wc -l < /etc/passwd(统计系统有多少个用户)

输出重定向:>

命令: echo “***” > filename

输出重定向:>>(追加式写入)

文本合并

方式一:cat a.txt b.txt > new.txt
方式二:使用vim打开a.txt,:r 路径/b.txt

输出重定向特殊使用方法

&>:忽略命令执行结果的错对,将输出写入到指定文件或设备

echo $?(查看上一条命令是否正确,正确输出0,错误输出非0)

逻辑

; :分隔命令(无逻辑关系,命令全部执行)
&&:同时成立才执行(前面执行成功后则后面开始执行)
||:其中一个成立即可执行(如果某一个命令执行成功了,后面的命令便不再执行)

管道符 |

ls -l /etc/ | more(翻页显示,空格翻页)

特殊符号

  • $:用于调用指定的变量的值,如 echo “$abc”
  • \:转义符
  • ‘’:引号内的所有符号失去特殊含义
  • “”:类似于单引号,除了”$”,”`”,”"三个符号外都没有特殊含义,常用于将某命令
  • ``:反引号,优先执行反引号中的内容

示例:

1
echo `date`	//取出date命令的执行结果传给echo

知识:

  • date:系统时间
  • clock:时钟时间

例子:

1
2
usernum=`wc -l < /etc/passwd`
echo $usernum

或者

1
2
usernuum=$(wc -l < /etc/passwd)
echo $usernum

UID范围

超级管理员:0
系统用户:1-999
普通用户:1000-65535

/sbin/nologin:禁止本地、远程登录
/bin/bash:可登录

变量的分类

  • 自定义(普通)变量
  • 环境变量
  • 位置参数变量
  • 预定义变量

set

作用:用来显示终端有哪些变量(显示所有变量)
选项:

  • -u

使用 set -u 命令之后,如果变量不存在,会报错,不会输出空值,避免了一些风险

示例:

1
2
set -u
rm -rf $a/*

unset

删除变量

注:特殊符号也可以顺序排列(转换为ASCII码)

普通变量

name= zhangsan ❌
name=zhang san ❌
name=zhangsan ✅
name=”zhang san” ✅

环境变量

尽量使用大写字母

声明规范

1
export NAME=zhangsan

如何区分普通变量与环境变量:
env:只显示环境变量

普通变量如何变成环境变量:
直接(重新)声明即可

例子:

1
env | grep 'PATH'

结果:

1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

这个环境变量很重要
我们执行的命令,都是通过这个变量作为引导来查询到相应的命令位置的
比如:

[root@localhost ~]# which ls
alias ls=’ls –color=auto’
/usr/bin/ls

which会查询到ls命令的所在位置,而 /usr/bin 就是环境变量PATH中的一个成员
如果PATH环境变量删除了,那么我们的所有命令将不可再使用
假设test是一个可执行程序

PATH=”$PATH:/tmp/test”
这条语句的意思就是添加一个新的命令,名为test

位置参数变量

使用例子来说明

vim test.sh

1
2
3
4
5
#!/bin/bash
echo $0
echo $1
echo $2
echo $3

bash test.sh
bash test.sh 11 22 33

测试1:

bash test.sh

1
test.sh

系统会默认把脚本的名称作为$0

测试2:

bash test.sh 11 22 33

1
2
3
4
test.sh
11
22
33
  • $* : 一次性输出所有变量
  • $@ : 依次输出变量
  • $# : 统计变量个数

测试3:

vi test.sh

1
2
3
4
5
#!/bin/bash

echo $*
echo $@
echo $#

bash test.sh 11 22 33 44

1
2
3
11 22 33 44
11 22 33 44
4

命令read

-p : 编写提示信息

例子:

vi test1.sh

1
2
3
#!/bin/bash
read -p "Please input your userid: " id
read -p "Please input your password: " password

chmod +x test1.sh
./test1.sh

进一步修改:

vi test1.sh

1
2
3
4
5
6
#!/bin/bash
read -p "Please input your userid: " id
read -p "Please input your password: " password
read -p "Please input your want to (+,-,*,/): " fix

echo $(($id$fix$password))

chmod +x test1.sh
./test1.sh

其实这只是一个骨架,可以想一下如果输入了字母,会出现什么情况?
所有还要进一步对输入进行判断,以后待我牛X了再进行补充.

运算

在shell中只支持整数型运算

如果想要使用浮点数,解决办法:

命令:bc(一般和管道符配合使用)
格式:echo $(echo “1.23*3.45”|bc)

特殊运算符

  • ++ : 一般用 let n++,意思是n的值每次自增1
  • += : 一般用 let n+=N,意思是n的值每次自增N
  • – : 一般用 let n–
  • -+ : 一般用 let n-=N

变量相关配置文件

加载顺序:/etc/profile —> ~/.bash_profile —> ~/.bashrc —> /etc/bashrc

cat /etc/profile

1
2
3
4
if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then
umask 002
else
umask 022

文件的最大权限:666

umask:002
666-002=664

umask:022
666-022=644

流程控制

if-else

单分支格式(注意空格):

1
2
3
4
5
6
if [ 判断条件 ];
then
语句1
else
语句2
fi

多分支格式:

1
2
3
4
5
6
7
8
9
if [ 判断条件1 ]
then
语句1
elif [ 判断条件2 ]
then
语句2
else
语句3
fi

具体:
[-选项 “变量”],然后借助 $? 在验证判断结果

-e:判断文件是否存在
-s:判断文件是否存在,并判断是否为非空
-f:判断文件是否存在,并判断是否是普通文件
-d:判断文件是否存在,并判断是否是目录文件
-b:判断文件是否存在,并判断是否是块设备文件
-L:判断文件是否存在,并判断是否是软链接文件

-eq:判断是否相等
-ne:判断是否不等
-gt:判断是否大于
-lt:判断是否小于
-ge:判断是否大于等于
-le:判断是否小于等于

-z:判断字符串是否为空
-n:判断字符串是否为非空
==:判断两个字符串是否相同
!=:判断两个字符串是否不同

-a:逻辑与,多个判断使用-a连接起来,所有条件成立则为真
-o:逻辑或,多个判断使用-o连接起来,任意条件成立则为真

for

语法一:

1
for 变量 in v1 v2 v3...

语法二:

1
2
3
4
for((初始值;循环控制条件;变量变化))
do
程序
done

例子:

vim test2.sh

1
2
3
4
5
6
7
8
9
#!/bin/bash

sum=0
for((i=1;i<=100;i++))
do
sum=$(($sum+$i))
done

echo $sum

chmod +x test2.sh
./test2.sh

案例(常用小工具):

利用脚本解压压缩包

压缩包的类型:

  • .zip
  • .tar
  • .tar.gz/.tar.bz2/.tar.xz/.tgz(解压命令:tar -xf filename)
  • .gz
  • .bz2

假设都是同一种类型

vim yasuo.sh

1
2
3
4
5
6
7
8
9
10
#!/bin/bash

read -p "scripts file path" path

cd $path

for i in `ls`
do
tar -xf $i
done

不是同一种类型

vim yasuo1.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash

read -p "scripts file path" path

cd $path

for i in `ls`
do
if [[ "$i" =~ ".zip" ]];then
unzip $i
elif [[ "$i" =~ ".tar" ]];then
tar -xf $i
else
echo "this type is unknow"
done

while

格式一:

1
2
3
4
while [ 条件判断式 ]
do
程序
done

格式二:

1
2
3
4
while true
do
程序
done

退出功能

  • exit:退出脚本
  • exit[值]:退出时如果定义好了返回值,那么我们可以通过 $? 来查看
  • break:退出循环
  • continue:直接开始下一次的循环

示例:

for i in 1 2 3 4 5 6 7 8 9
do
if [ “$i” -eq “4” ]
then
break
else
echo “$i”
fi
done

随机数:

echo $RANDOM
echo $(($RANDOM%100))

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash

num1=`echo $(($RANDOM%100))`

while true
do
read -p "Please input a number[1-100]: " num2
if [ "$num2" -gt "$num1" ]
then
echo "you win"
elif [ "$num2" -lt "$num1" ]
then
echo "you false"
else
echo "you guess"
fi
done

本文标题:shell的使用方法

文章作者:尚先森

发布时间:2020年09月16日 - 17:42:37

最后更新:2022年07月27日 - 13:59:44

原始链接:https://imauu.gitee.io/2020/09/16/shell的使用方法/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

尚先森 wechat
有任何问题可以扫描上方二维码私聊我哦😊
您的支持是我创作的最大动力^_^