shell学习笔记

一、shell基本命令回顾
1.1 查看文件和目录的命令
ls:列出目录下的清单;
cat:连接显示文件内容;
less/more:分页显示文件内容,建议使用less,相比于more更方便;
head:显示文件头部,可指定行数,默认显示10行;
tail:显示文件尾部,可指定行数,默认显示10行;
file:显示文件类型;
wc:查看文件或统计信息;
find:查找文件或目录;
1.2 操作文件和目录
touch:创建新文件(可以直接使用vim/vi/gredit等编辑器直接创建)
mkdir:创建目录,可以利用 -r选项递归创建
cp: 拷贝命令,拷贝目录时可以使用 -r 选项
ln: 创建链接命令,分为软连接和硬链接(有专门的文章介绍)
mv: 移动文件或者目录的命令,同时也是改名命令
rm: 删除命令,-r 删除目录, 谨慎使用;
1.3 管理文件或者目录的权限
ls -l : 可以列出文件和目录的权限信息;
chmod: 修改文件和目录的权限(需要了解字母及数字权限表示)
chown/chgrp: 改变属组和属主
setuid/setgid:设置用户或组权限位;
1.4 文本处理命令
sort : 文本排序
uniq : 文本去重
tr : 替换命令
grep : 查找字符串
diff : 文件对比,找出文件差异
1.5 其它常用的命令
hostname : 查看主机名
w , who : 列出系统登录的用户
uptime : 查看系统运行时间
uname : 查看系统信息
date : 显示和设置系统日期和时间
id  : 显示用户属性
1.6 shell命令进阶
paster : 合并文本
dd : 备份和拷贝文件(和vim 和剪切命令一样)
tar : 打包和解包文件
mount, umount : 挂载和卸载存储介质
df : 报告文件系统磁盘空间利用率
du : 评估文件空间利用率
ps : 查看系统的进程
pidof : 列出进程的pid
top : 相当于 Linux 的任务管理器
& : 将作业后台运行
jobs : 查看作业
bg : 让挂起的进程在后台继续执行
fg : 将后台进程放入前台
fdisk: 查看系统的磁盘信息

举例:
在这里插入图片描述
前后台切换演示:
在这里插入图片描述
解释: 先执行 sleep 100 & 让这个进程在后台执行,然后我们先使用 ps 配合 grep 命令查看一下 sleep 进程的信息,接着 jobs 查看一下后台运行的作业, 使用 fg 命令使其继续在前台执行,我们可以看到显示了sleep 100 , 接着我们又不想让他继续执行了,使用 ctrl + z 使其挂起,我们用jobs查看,可以看出其处于 stopped 状态,接着使用 bg 命令使其继续在后台执行,查看状态, 处于running状态;

二、 shell基本语法学习
2.1 shell 编程基础

1)基本格式

#!/bin/bash
echo "hello world"

分析:还是 hello world 起步,第一行的 #!叫做 Shebang, 然后后面的 /bin/bash 则是指定解释器,既然shell是门解释性语言,自然需要解释器,类似的,如果是 python脚本,则是 #!/bin/python 可能还需要一些编码格式的规定(utf - 8),如果没有指定解释器,默认选择 sh ; 同时还需要给文件可执行权限,否则会报错,虽然我们一般把shell 脚本文件命名为 .sh 的文件(在Linux中文件后缀只能起到标识的作用,没有实际意义);

2)shell 中的注释,在shell中注释的符号是 “#”;

3)shell的变量

  • 在shell中设置变量和平时在命令行设置变量是一样的,可以直接定义一个变量,例如: a=10 不需要声明类型,不需要分号;

  • 如果需要明确指定变量的类型的话,可以只用declare的选项指定类型;

  • 变量的作用域:在shell 中,变量默认都具有全局属性,如果需要局部的变量则需要在变量的声明处加 local 关键字。如: local a=10

  • 变量的操作:

    • 获取变量的值在命令行获取变量的值是通过 echo ${a} 打印变量的值到终端的,那么echo的作用是打印,’${}'的作用不言而喻(花括号可省略,起分割的作用)。

    • 变量的运算
      let a+=1,即使用 let 命令,当然除了 let 命令还有 ‘(())’ 双括号,都可以进行变量的运算;

    • 参数变量
      说到shell的参数,有两个点,一个是命令行参数,一个是函数的参数,这里先说明命令行参数,函数的参数在后面学习函数的时候补充;

  • 变量说明:

$$  	Shell本身的PID(ProcessID)  	
$!  	Shell最后运行的后台Process的PID 
$?  	最后运行的命令的结束代码(返回值)  	
$-  	使用Set命令设定的Flag一览  	
$* 	 	所有参数列表。如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。  	
$@   	所有参数列表。如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。  	
$#    	添加到Shell的参数个数  	
$0  	Shell本身的文件名  	
$1~$n 	添加到Shell的各参数值。$1是第1参数、$2是第2参数…

例子:
在这里插入图片描述
注:取消变量的定义 unset

4) shell环境变量和普通变量

首先,明确两点,第一点即环境变量和普通变量在虚拟地址空间的存放位置,环境变量在栈顶的位置(高地址处),而普通变量是在数据段存放的;第二点,子进程会继承父进程的环境变量;

普通变量的命令行声明: a=10
将普通变量变为环境变量:export a

如何验证?

1、在父bash 中声明变量 a=10, 命令行敲 ‘bash’ 命令相当于起了一个子bash, 在子 bash 中查找是否有 a变量;
在这里插入图片描述
(set 命令查看所有变量, env 命令查看所有环境变量,exit或者ctrl + d 退出子bash)

2、在父bash 中将变量 a 声明为环境变量 ‘export a’, 在子bash 中查看变量 a;
在这里插入图片描述

2.2 if条件执行

shell的条件执行其实和C差不多,具体的差异就在于语法格式的一些差别;

不同于C的是,bash的条件测试不单单只是可以通过if进行判断,还要结合一些特殊的符号,命令和参数;

先列出基本的if语句的使用格式:

if true
then
    echo "hello world!"
else
    echo "see you world!"
fi 

这就是 if 语句的基本使用格式,当然,中间还可以有‘elif’相当于 C 的 else if ; 值得注意的是开始的 then和最后的 fi , 每个 if 都必须有一个fi 与之对应代表结束,因为没有了 ‘{}’;

前面说了,shell的条件判断需要结合一些命令,符号,选项来配合使用;

‘[]’ 和 test 都被用作测试,如:

if [ -f install.log ]
then
    echo "hello"
fi

test -f install.log; echo "hello"

‘[ ]’ 和 test 有很多选项,这里我就不一一演示,需要的话直接 man test; ( 注意: 使用 ‘[ ]’ 时, 需要两个空格,‘[’的后面, ‘]’的前面各一个);

不但这些,还有比较的符号,其中又分字符串和算数的不同;

字符串:

选 项作 用
-z str判断字符串 str 是否为空。
-n str判断宇符串 str 是否为非空。
str1 = str2 或 str1 == str2=和==是等价的,都用来判断 str1 是否和 str2 相等。
str1 != str2判断 str1 是否和 str2 不相等。
str1 > str2判断 str1 是否大于 str2。>是>的转义字符,这样写是为了防止>被误认为成重定向运算符。
str1 < str2判断 str1 是否小于 str2。同样,<也是转义字符。

算术:

操作符描述
< INTEGER1 > -eq < INTEGER2 >如果< INTEGER1 >与< INTEGER2 >相等则为真
< INTEGER1 > -ne < INTEGER2 >如果< INTEGER1 >与< INTEGER2 >不相等则为真
< INTEGER1 > -le < INTEGER2 >如果< INTEGER1 >小于或等于< INTEGER2 >则为真
< INTEGER1 > -ge < INTEGER2 >如果< INTEGER1 >大于或等于< INTEGER2 >则为真
< INTEGER1 > -lt < INTEGER2 >如果< INTEGER1 >小于< INTEGER2 >则为真
< INTEGER1 > -gt< INTEGER2 >如果< INTEGER1 >大于< INTEGER2 >则为真

追加一个知识点: 因为字符串的比较使用 ‘[]’ 时需要对 ><进行转义,所以shell提供 ’ [[ ]] ’ 符号,则不再需要转义,对于算术,shell提供 ’ (( )) ’ 则可以直接使用比较符进行比较;

2.3 &&和||
  • && : &&符号的前面的表达式为真才会执行 &&后面的表达式;
  • || : || 符号前面的表达式为假才会执行 || 后面的表达式;
  • ‘!’: 逻辑非

通常 && 和 || 配合使用,如:
在这里插入图片描述

2.4 shell 的 case 语句

shell的case语句的格式如下:

case $1 in 
1)
    echo "1"
    ;;
2)
    echo "2"
    ;;
esac

上面就是case语句的格式,这里刚好提醒一点,就是在shell中,不允许出现空语句,如果非要有空语句,则必须写上一个 冒号‘:’;

2.5 bash 循环

shell的循环:for/while/until,下面只演示前两种,until不太用到;

for循环

for i in $(seq 10)
do
    echo -n $i
done

#类C 的for 循环:

for (( i=0; i<10; ++i ))
do
    echo -n $i
done 

注: seq 是生成连续序列的命令,而shell中执行命令的话,会用 ‘$()’;
echo -n 选项则是取消换行,每个echo语句都会带一个换行,直接一个echo则代表换行;

while循环

值得一提的是break和continue关键字在shell中依然有效;

i=1
while true
do
    if [ $i -gt 2 ];then
        echo $i
        break
    fi
    let i++
done

continue语句不做演示;

2.6 shell的函数

首先,shell函数的定义:

function  fun()
{
    if [ $# -ne 2 ];then
        return 1
    fi
    local a=$1
    local b=$2
    let c = a + b
    echo "hello $c"
    return 0
}

fun 1 2
if [ $? -ne 0 ];then
    echo "arguments fault!"
    exit
else
    echo "used right"
fi

上面就是一个简单的脚本,起作用是调用一个fun函数,判断调用是否正确;

分析: 从这个脚本中我们可以看出shell脚本函数的使用方式,从定义到参数的获取,再到返回值;最后还有函数的调用方式其实和命令的执行方式是一样的;

(注: function关键字可以省略但不建议,return 可以返回的值是 0-255)

额外知识点: 在shell脚本中 双引号 和 单引号是有区别的,虽然在大部分场景中它们是一致的,但是如果含有特殊字符的话,双引号是没有对特殊字符进行转义的,所以上面的脚本中 “hello $c”可以顺利执行,但是单引号的话默认会对特殊字符转义的,例如:
在这里插入图片描述

2.7 shell 重定向

说起重定向,估计不少同学都想到了管道;

但是,管道并不是重定向,重定向是将一个命令的输出结果作为下一个命令的输入,而重定向是将输出和文件相链接的;

重定向分为输入重定向和输出重定向,其中又有追加和覆盖的区别,总的来说就是下面四个符号:

’ > ‘, ’ >> ‘, ’ << ’ , ’ < ‘;

举例来说:
在这里插入图片描述
当然,不仅可以这样,还可以将标准错误也重定向到文件;

ls l 2>test.sh

输入重定向:
在这里插入图片描述
注: 这里的END不是固定的,只是起一个标签的作用,代表下次遇到END就结束输入;

重定向的这种用法还被用到项目中的configure文件,使configure文件可以自动生成Makefile文件,例如:
在这里插入图片描述

2.8 shell 脚本从标准输入读取

这个其实只是一个read的使用,在shell中使用read从标准输入读取数据;

例如:

#! /bin/bash

read -p "login name:" name
read -p "passwd:" passwd

read -p "display information? [y/n]" choose
if [ $choose = 'y' ];then
	echo $name
	echo $passwd
fi

结果:
在这里插入图片描述

三、sed/awk工具
3.1 sed

sed是一行一行处理文本的,还有需要知道sed有一个HOLD空间和模式空间,HOLD用来作为文档处理的暂存空间,不能有任何的操作,所有的操作只能在模式空间进行;

sed常用的选项:

-e : 它告诉sed将下一个参数解释为sed指令,即需要连续多个处理时使用;
-f : 指定由sed指令组成的脚本的名称;
-i : 直接在读取的内容进行修改,如果没有—i,不会源文件造成任何修改;
-n : 静默模式,即只输出匹配的行,如果没有-n则匹配行会和源文件全部输出;

sed的编辑命令有24个之多,在这里只学习常用的几个:

追加(a),更改(c),删除(d),插入(i),替换(s),打印(l),打印行号(=),转换(y);

例子:
在这里插入图片描述
下面这些选项则是需要用到暂存空间时要用到的选项:

+ g:[address[,address]]g 将hold space中的内容拷⻉贝到pattern space中,原来pattern space里的内容清除
+ G:[address[,address]]G 将hold space中的内容append到pattern space\n后
+ h:[address[,address]]h 将pattern space中的内容拷贝到hold space中,原来的hold space里的内容被清除
+ H:[address[,address]]H 将pattern space中的内容append  hold space\n后
+ d:[address[,address]]d 删除pattern中的所有行,并读入下一新行到pattern中
+ D:[address[,address]]D 删除multiline pattern中的第一行,不读入下一行
+ N,添加下一行至pattern space内;
+ x:交换保持空间和模式空间的内容

求1~100的和

两种方式:
在这里插入图片描述
分析:第一个例子利用了暂存空间和模式空间的特点进行求和,其中 $ 代表最后一行; ‘^’ 代表第一行; 然后利用选项H 和 x; 其中利用sed的s编辑命令和正则表达式把换行换为加号,最后通过管道把表达式交给bc计算器,得到最终结果;

第二个例子则是利用sed的标签,没有用到暂存空间; 其中 :a是设置了一个 a标签, ba的作用是跳转到a标签;

3.2 awk工具

既然有了sed为什么还要有awk呢? 肯定是因为awk比sed更加强大,就最明显的一点,sed只能一行一行处理数据,不能处理一列一列的数据,而awk就可以做到,而且awk还可以利用类C的语法结构,简直强大;

找出你在Linux上最常用的十个命令:

history | awk ‘{print $1}’ | sort | uniq -c | sort -nr |head

awk 的默认的列分割符是空格,我们也可以指定分割符,利用 -F选项;

例如:
在这里插入图片描述
`awk 还有一个特点就是它的 BEGIN 块和 END 块;

BEGIN块的作用是在awk执行匹配之前先执行的语句,END自然就是awk处理完之后执行的语句;

例如:
在这里插入图片描述

原文链接:https://blog.csdn.net/bitboss/article/details/73019967

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值