bash shell

基础命令

基础查询指令 info会详细介绍

man cmd

info cmd

用于跳转到指定目录 以及打印当前目录

cd

pwd

查看当前目录列表 查看当前的目录树

ls

ll (options: -F -a -R -l -i )

tree(可能需要先安装)

创建文件 拷贝文件 移动与重命名 删除

touch

cp src dest

mv

rm (常用 -f 强制删除 -r 删除文件夹)

创建目录 删除文件夹

mkdir

rmdir (有文件会导致删除失败)

查看文件类型 查看文件内容

file

cat

more (分页显示)

less (支持上下分页)

进阶命令

显示进程信息 进程资源 结束进程

ps (options: -A -a -d -l -H -f )

top

kill (常用 -9 无条件终止)

磁盘空间查看 查看指定目录占用

df

du (options: -c -h -s )

数据排序 数据搜索

sort

grep [ -r -n -v -c -e -a -w ] pattern [file]

压缩 与解压

zip unzip

gzip gunzip

数据归档

tar

-A 将已有归档追加到另一个已有的归档文件

-c 创建一个新的归档文件

-d 检查归档文件和文件系统中文件的不同

-delete 从归档文件中删除

-r 追加到归档文件末尾

-u 追加新的同名文件

-x 从已有的归档文件中提取文件

-f 指定归档的文件名,一般为最后一个参数,指定文件名

-p 保留文件权限

-v 处理文件时显示文件

-z 有gzip属性的 gz

更改文件权限

chmod (change mode)

八进制修改 +-修改

chmod 777 file

chmod u+x file

u 用户 g 组 o 其他用户 a 所有

rwx 读写执行

chown (change owner)

============================================

文件权限说明

-rw-rw-r-- 1 ted ted 1369 Mar 12 23:35 .emacs.bak

drwx------ 20 ted ted 4096 Aug 9 19:30 .emacs.d/

drwxrwxr-x 5 ted ted 4096 Apr 27 14:09 .eric6/

↑共有十个字符

第一个字符代表:-代表文件,d代表目录,l代表链接,c代表字符设备,b代表块设备,n代表网路设备

后面9个字符分为三组,rwx代表-可读,可写,可执行

三组对应权限:所属用户,用户所在组,其他用户

基础脚本编写

touch 一个.sh的脚本文件用VIM打开 并输入以下几行内容:

#!/bin/bash 第一行 可以指定使用的shell echo 则是打印 打印信息 $HOME 环境变量前面加 $ 使用环境变量,如果需要显示$,需要转义 $ 为 \ $ Key=Value 需要中间不能用空格

我们使用chmod为脚本文件添加可执行权限 使用bash+file位置使用我们自己定义的sh脚本 也可以用./test.sh 启动脚本 需要注意的是不能直接通过名字启动,linux会认为你使用的是指令而不是sh脚本 可以通过导出当前的pwd,使得在任意位置可以直接通过文件名启动sh

退出状态码

linux提供了 $? 变量来记录上一个命令退出的状态码 状态码有以下种类,当然也可以通过 exit num 指定退出状态码

状态码description0上一个命令成功结束1发生了未知的 error3不是一个合适的 shell 命令126命令不可执行127命令不存在130使用 ctrl+c 中断255正常状态码之外的状态码

重定向输入输出与管道操作

输出重定向 通过 > 可以将输出的内容重定向到指定文件 需要注意的是 > 会清空文件里的内容 与之相对的还有一种 >> 操作,会在文件里追加内容而非覆盖 也可以输入重定向 wc是一个统计字符的操作 通过wc < test.sh 能统计行数与字符数据 管道操作符 通过管道操作符可以把前一个命令的输出作为 | 之后命令的输入,我们在所有的进程中找跟系统相关的进程

数学运算相关

expr基础命令

expr 执行数字运算(一定是整数) 需要注意的是赋值的=号两边不能有空格 但是expr 做数值运算时,操作符的两边要有空格,且乘法更是需要转义

2. 方括号版 使用方括号就较为简单粗暴,不需要使用转义符也能达到效果 3. 如何处理浮点数 使用内置的计算器,命令为bc 使用方式上可以使用管道符的方法 如下所示: 通过指定scale可以控制现在的小数点位数

条件控制(if)

基础结构如图所示,需要注意以下几点

if后跟的是命令,且只有这条命令的执行退出状态码为0才会触发then里的内容可以有多条 else ,可以嵌套使用 if 可以看到 if 里的 ls 一样打印了结果,最终触发的是的结果是 666

条件控制(test)

因为 if 只能通过状态码来判断要不要执行then里的内容,需要测试某个条件是否成立时,可以使用test命令来实现,基本的使用方式如下: 我们判断两个值是否存在,存在返回0,不存在返回错误的状态码 在bash中使用 [ ],能达到和test一样的效果,如下所示: 此处value1的值为9,value2为2,所以输出了9,下面放一个表,用来展示[]与test的比较和使用方式:

test[ ]str1 = str2n1 -eq n2str1 != str2n1 -ne n2str1 \ < str2n1 -lt n2str1 \ > str2n1 -gt n2>=n1 -ge n2<=n1 -le n2

只是>或者< 需要前面加反斜杠转义 数值比较只能是 整数

if-then的一些高级特性

双括号命令允许使用高级数学表达式 图1展示了使用双括号向左位移两位后是否大于指定数的判断,value2的值为2,向左移动两位等于扩大这个值为原来的4倍,即2X2X2=8,图一中的判断条件刚好为8,所以判断失败,不能执行then的内容,二图中将条件改为7后成功执行打印了新的value2的值双方括号,提供了字符串高级比较特性,双方括号的用法和test中定义的用法相同,但是额外提供了一个test命令当中没有提供的特性,那就是正则表达式

条件控制(case)

case,可以达到多个if-else的效果 使用方式如下所示,通过 | 可以一次匹配多个条件,* 则是在前面的条件匹配失败后可以匹配所有的选项

循环控制(for)

for循环,使用方法是 for A in ListB do something done 通过循环给char赋值,并打印char的值

循环控制(while)

while循环,比起for不同的是判断的是条件的执行结果 需要值得注意的是,一样可以使用方括号,shell中的赋值一定要在前面加上$符号,否则会提示找不到命令,导致死循环!

循环控制(until)

until与while恰好相反,until是判断的条件状态码不为0时执行,适用方式与while一致

循环控制(break与continue)

break和continue,用法与在C语言中的使用方式基本相同,在这个二重循环中,使用break提前跳出,但是与C语言不同的是,可以通过 break n 指定跳出的层数,可以一次跳出多层循环!

循环控制(重定向与管道)

重定向 之前的重定向操作在此处也可以使用,比如使用 > 或者 >> 进行重定向输出 可以看到我们将命令执行的结果在done的位置,通过重定向符将结果导向我们的log文件中,查看log文件可以看到之前打印在控制台中的信息。管道符 通过 | 我们可以将输出的结果传入sort,我们得到的结果就会是整理后的结果,如下图所示,我们传入一个打乱的数组,打印的会是一个整理后的结果:

输入输出(读取参数)

可以在命令行后追加参数,使得命令以有参的方式执行,我们自己编写的shell自然也可以这样做,$0代表文件本身的名称,$1至$9代表传入的1至9个参数,使用方式如下所示: 我们通过$1 和 $2成功接收到了外部传递的hello 和 world两个arg

输入输出(参数信息,抓取变量与shift)

$# 代表所有参数的个数,当我们想要知道最后一个参数是什么的时候可以使用 $ {!#} ,为什么不是 $ {$#},因为花括号内不能用 $ ,所以需要用!来代替 $$* 拿到所有参数组成的字符串,不可以遍历$@ 拿到所有参数组成的列表,可以遍历shift命令可以移动变量,shift N可以使所有变量向左移动N位,此处向左移动一位后,1号位hello变量由2号位world代替,但是0号文件名不会变

数据控制(重定向)

在脚本中使用重定向之前,先插入一个标准文件描述符

文件描述符缩写0STDIN1STDOUT2STDERR

1.使用输入重定向时,linux会用指定的文件去替换标准输入文件描述符 2.使用输出重定向可以用来改变输出重定向的指向 3.默认情况下,标准错误输出也是和标准输出一样,输出到屏幕上面,但是STDERR不会随着STDOUT的重定向而改变。

标准的重定向使用方法应该如图所示

将错误输出到指定的filename将错误输出到err_filename,将正常输出重定向到log_filename中将错误输出和正常输出重定向到同一个文件中

数据控制(脚本中的重定向)

临时重定向 exec 永久重定向 有时候我们需要一大片的内容都输出到指定文件,而我们又不想要每次都去重定向一下,比如频繁的将echo的内容重定向,就可以使用exec实现永久的重定向,具体使用方法如下: 在 exec 1>log 之后正常输出的结果都会打印到log中 在 exec 2>error 之后错误输出的结果都会打印到error中 重定向输入 使用 exec 0< filename 即可从文件中重定向输入,这里笔者故意在0和<中间多打了一个空格,错误的结果成功写入到了之前重定向的error中 创建重定向输出 可以通过exec命令文件描述符分配重定向的文件,这里我们创建了一个描述符为3的输出,并且我们指定我们的语句的结果输出到log2。 重定向输出文件描述符 我们可以将文件描述符的结果重定向到另一个文件描述符,使用方式如图所示 创建输入文件描述符与重定向输入文件描述符 有了第五步的操作,我们自然也可以将输入也重定向,这里我们编写一个sh文件,他的效果就是打印其他文件中的内容 第一步,把文件描述符6的输入定向到0的输入 第二步,把文件描述符0的写入定向到test2.sh的读取 第三步,循环读取test2的数据并打印到屏幕上 关闭文件描述符

虽然bash shell会自动在脚本结束时关闭所有的文件描述符

也可以使用这个指令在需要的时候手动关闭

exec 3>&-

这样可以关闭句柄为3的文件描述符

数据控制(阻止执行)

有时候你可能不想显示脚本的输出,比如说你想将脚本当做后台程序运行,这时候你应该阻止文件的输出。linux下有一个特殊文件,就是 /dev/null,null文件和他的文件名一样,文件里面什么都没有,输出到null文件里面到任何数据都不会保存,全部都丢掉了。

数据控制(查看文件描述符)

查看文件描述符可以通过 losf 命令来实现 比如这样: 其中需要解释的是 -a :将满足要求的数据取交集(因为使用了-p和-d) -p :查找指定进程的数据 $$ 代表的是当前进程的进程号 -d :查找指定类型的文件描述符(FD中 第一位代表的含义)

处理信号(信号类别)

名字值简介SIGHUP1挂起进程SIGINT2终止进程SIGQUIT3停止进程SIGKILL9无条件终止进程SIGTERM15尽可能的终止进程SIGSTOP17无条件停止,不是终止SIGTSTP18停止或者暂停,不终止进程SIGCONT19继续停止运行的进程

bash shell会忽略收到的SIGQUIT和SIGTERM信号

处理信号(生成信号)

1.通过输入ctrl c组合键发送SIGINT信号停止shell当前运行的进程。 使用ctrl+c 终止了top继续查看资源资源

2.通过输入ctrl+z组合键生成一个SIGTSTP信号,停止shell中运行的任何进程,但是停止的进程会继续保留在内存当中,可以通过fg命令恢复暂停的进程。可以通过ps -l查看当前暂停的作业 ctrl+z暂停进程,能看到被stop的top命令

3.使用kill -9 Pid 发送SIGKILL命令干掉进程 这里我们使用kill -9 干掉了刚刚暂停的top进程

处理信号(捕获信号)

在脚本中可以使用trap指令手动捕获linux信号,使用方法如图所示 trap + 命令 + 信号名称

执行后会持续九个循环,每个循环使得count计数加一,同时中间会休眠两秒以延长这个循环执行的时间,同时我们使用 ctrl+c 信号持续刺激脚本,执行结果如图: 捕获退出信号只需要在添加 trap 命令 EXIT 即可捕获脚本的退出信息

后台运行(&)

在命令的最后添加一个 &即可使得脚本在后台运行,需要注意的是每一个后台进程都对应一个终端,终端挂掉会导致后台进程挂掉 我们将刚刚写的循环运行至后台并查看: 第一,后台运行执行后会返回该后台进程的进程ID,如图为1478 第二,我们马上通过ps -a 查看正在运行的进程,看到了我们的1478脚本进程,同时还有一个1480sleep进程,这个进程是我们的脚本拉起的进程 第三,我们在前端使用ctrl+c的信号无法再被后台进程所捕获,这种情况下无法通过信号控制后台进程。 第四,如果我们希望终端的停止不会影响到我们的后台进程,可以通过使用nohup命令来拦截所有的SIGHUP信号,同时切断进程和终端的联系,所有的输出都会追加到一个nohup.out文件当中。

作业控制(查看,继续,优先级)

使用jobs看来查看正在执行中的作业,比如我们自定义的test4循环作业 可以接受的参数: -l :列出PID和作业号 -n :列出上次shell发出通知后改变状态的作业 -p :列车PID -r :只列出运行的作业 -s:只列出停止的作业 通过bg或者fg加上作业后可以继续暂停中的后台job 通过nice或者renice调整谦让度 nice -n 10 command 或者 renice -n -20 -p PID 调度优先级就是内核分配给进程的CPU时间。在linux当中,有shell启动的所有进程的调度优先级都是相同的。调度优先级是整数,从 -20(最高优先级) 到 19(最低优先级)。

作业控制(定时作业)

TODO

函数(创建与使用)

创建的方式共有三种 第一种是,function fun_name{} 第二种是,function fun_name(fun_args){} 第三种是,fun_name(fun_args){} 这里演示第三种我们先定义了一个hello函数,并在下面调用了该函数,值得注意的是,使用函数一定是在函数的定义之后才可以

函数(返回值,参数与变量)

返回值(return) 函数的返回值,也就是指函数执行的结束状态码,这个值的范围是0-255 以下是一个return的返回示例: 我们使用read获取了一个屏幕的输入值,并且返回这个read的执行状态码,这里我们正常执行的值一定是0,所以return了一个0出去,我们在shell中通过 $? 拿到了上一次的状态码为0(提示是说0并不是一条命令,但是状态码确实是0)参数 传参的手段与上文所描述的读取参数的手段一致,这里给出示例: 值得注意的是,需要在函数的外部获取参数值,在函数的内部无法获取到传入脚本的参数值变量 第一,脚本中的函数只会在当前shell环境中生效 第二,shell脚本中变量默认全局有效 第三,使用local可以将变量限定在函数内部 这里我为了区分 分别使用了三个不同的echo来展示变量的作用范围 可以看到,无论我是否传入了参数,第一个change都改变了全局的a和b,覆盖了我们传入的a和b的值,第二次echo两个值是在changeInside内部产生的作用,这个值只会应用在函数的内部,第三次我们打印a和b的值时和第一次打印的值是一致的

函数(外部调用)

函数的外部调用共有两种方式 第一种,在脚本的内部直接引入我们想要引入的脚本文件,这样我们就可以使用引入的文件内部的函数 第二种,直接source加载我们的脚本,然后就可以直接引用脚本中的函数 通过source + 绝对路径,我们可以直接在bash中调用内部的函数

文章来源

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。