首页 > 系统相关 >Shell学习笔记

Shell学习笔记

时间:2024-07-09 18:01:55浏览次数:18  
标签:10 12 centos shells VM 笔记 学习 Shell root

一、概述

Shell是一个命令行解释器,它接收应用程序/用户命令,然后调用操作系统内核。

Shell还是一个功能相当强大的编程语言,易编写、易调试、灵活性强。

Linux提供的Shell解释器

[root@VM-12-10-centos shells]# cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
/bin/tcsh
/bin/csh

bash与sh的关系

[root@VM-12-10-centos bin]# ll | grep bash
-rwxr-xr-x  1 root root      922792 12月 19 2021 bash
lrwxrwxrwx  1 root root          10 8月   7 2020 bashbug -> bashbug-64
-rwxr-xr-x  1 root root        6964 4月   1 2020 bashbug-64
-rwxr-xr-x  1 root root      964536 12月 19 2021 bash_onion_sap1013.old
lrwxrwxrwx  1 root root           4 8月   7 2020 sh -> bash

Centos默认的解释器是bash

[root@VM-12-10-centos bin]# echo $SHELL
/bin/bash

二、Shell脚本入门

脚本格式:脚本以#!/bin/bash开头(指定解析器)。

# 创建一个Shell脚本,输出hello world
[root@VM-12-10-centos bin]# touch test.sh
[root@VM-12-10-centos bin]# vim test.sh

# 在test.sh中输入以下内容:
#!/bin/bash
echo "hello world"

脚本的常用执行方式:

  1. 采用bash 脚本的相对路径或绝对路径sh 脚本的相对路径或绝对路径(不需要赋予脚本执行+x权限)。

    • bash 脚本的相对路径

      [root@VM-12-10-centos bin]# bash ./test.sh 
      hello world
      
    • sh 脚本的绝对路径

      [root@VM-12-10-centos bin]# sh /bin/test.sh 
      hello world
      
      
  2. 采用输入脚本的绝对路径或相对路径执行脚本(必须具有可执行+x权限)。

    (1)首先赋予test.sh脚本的执行+x权限;

    [root@VM-12-10-centos bin]# chmod +x test.sh
    [root@VM-12-10-centos bin]#
    

    (2)执行脚本。

    # 相对路径
    [root@VM-12-10-centos bin]# ./test.sh 
    hello world
    # 绝对路径
    [root@VM-12-10-centos bin]# /bin/test.sh 
    hello world
    
    

注:第一种执行方法,本质是bash解释器帮助执行脚本,所以脚本本身不需要执行权限。而第二种执行方法,本质是脚本需要自己执行,所以需要执行权限。

第三种Shell脚本执行方法:在脚本的路径前加上.source

假设有以下脚本:

[root@VM-12-10-centos shells]# cat test.sh 
#!/bin/bash
A=1
echo $A

分别使用shbash./.的方式来执行,结果如下:

[root@VM-12-10-centos shells]# bash test.sh 
1
[root@VM-12-10-centos shells]# echo $A

[root@VM-12-10-centos shells]# ./test.sh 
1
[root@VM-12-10-centos shells]# echo $A

[root@VM-12-10-centos shells]# . test.sh
1
[root@VM-12-10-centos shells]# echo $A
1

前两种方式都是在当前shell中打开一个子shell来执行脚本内容,当脚本内容结束,则子shell关闭,回到父shell中。

第三种,也就是使用在脚本路径前加.或者source的方式,可以使脚本内容在当前shell里执行,而无需打开子shell!这也是为什么我们每次要修改完/etc/profile 文件以后,需要source一下的原因。

开子shell与不开子shell的区别就在于,环境变量的继承关系,如在子shell中设置的当前变量,父shell是不可见的。

三、变量

3.1 系统预定义变量

常用系统变量

$HOME$PWD$SHELL$USER等。

# 查看系统变量的值
[root@VM-12-10-centos shells]# echo $HOME
/root
# 显示当前Shell中所有变量
[root@VM-12-10-centos shells]# set
ABRT_DEBUG_LOG=/dev/null
BASH=/usr/bin/bash
......

3.2 自定义变量

基本语法

  • 定义变量变量名=变量值(注:=前后不能有空格)
  • 撤销变量unset 变量名
  • 声明静态变量readonly 变量(注:不能unset

变量定义规则

  • 变量名称可以由字母数字下划线组成,但是不能以数字开头,环境变量名建议大写
  • 等号=两侧不能有空格。
  • 在bash中,变量默认类型都是字符串类型,无法直接进行数值运算。
  • 变量的值如果有空格,需要使用双引号""或单引号''括起来。
  1. 定义变量A。

    [root@VM-12-10-centos shells]# A=1
    [root@VM-12-10-centos shells]# echo $A
    1
    
    
  2. 给变量A重新赋值。

[root@VM-12-10-centos shells]# A=2
[root@VM-12-10-centos shells]# echo $A
2

3. 撤销变量A。

```bash
[root@VM-12-10-centos shells]# unset A
[root@VM-12-10-centos shells]# echo $A


4. 声明静态变量B=2,不能unset。

```bash
[root@VM-12-10-centos shells]# readonly B=2
[root@VM-12-10-centos shells]# echo $B
2
[root@VM-12-10-centos shells]# B=3
bash: B: readonly variable

5. 在bash中,变量默认类型都是字符串类型,无法直接进行数值运算。

```bash
[root@VM-12-10-centos shells]# C=1+2
[root@VM-12-10-centos shells]# echo $C
1+2

6. 变量的值如果有空格,需要使用双引号或单引号括起来。

```bash
[root@VM-12-10-centos shells]# D= Hello Shell
bash: Hello: command not found
[root@VM-12-10-centos shells]# D="Hello Shell"
[root@VM-12-10-centos shells]# echo $D
Hello Shell

7. 可把变量提升为全局环境变量,可供其他Shell程序使用。

```bash
export 变量名

在test.sh文件中echo $B

[root@VM-12-10-centos shells]# vim test.sh
[root@VM-12-10-centos shells]# cat test.sh 
#!/bin/bash
echo "Hello Shell"
echo $B
[root@VM-12-10-centos shells]# ./test.sh 
Hello Shell

发现并没有打印输出变量B的值,将变量B提升为全局环境变量后。

[root@VM-12-10-centos shells]# cat test.sh 
#!/bin/bash
echo "Hello Shell"
echo $B
[root@VM-12-10-centos shells]# ./test.sh 
Hello Shell

[root@VM-12-10-centos shells]# export B
[root@VM-12-10-centos shells]# ./test.sh 
Hello Shell
2

## 3.3 特殊变量

### $n

`$n`:n为数字,`$0`代表该脚本名称,`$1`-`$9`代表第一到第九个参数,十以上的参数需要大括号`{}`包含,如`${10}`。

```bash
[root@VM-12-10-centos shells]# vim parameter.sh 
[root@VM-12-10-centos shells]# cat parameter.sh 
#!/bin/bash
echo '=====$n====='
echo $0
echo $1
echo $2
[root@VM-12-10-centos shells]# chmod 777 parameter.sh 
[root@VM-12-10-centos shells]# ./parameter.sh x y
=====$n=====
./parameter.sh
x
y

$#

$#:获取所有输入参数个数,常用于循环,判断参数的个数是否正确以及加强脚本的健壮性。

[root@VM-12-10-centos shells]# vim parameter.sh 
[root@VM-12-10-centos shells]# cat parameter.sh 
#!/bin/bash
echo '=====$n====='
echo $0
echo $1
echo $2
echo '=====$#====='
echo $#
[root@VM-12-10-centos shells]# ./parameter.sh x y
=====$n=====
./parameter.sh
x
y
=====$#=====
2

$*、$@

  • $*:这个变量代表命令行中所有的参数(把所有的参数看成一个整体)
  • $@:这个变量也代表命令行中所有的参数(把每个参数区分对待)
[root@VM-12-10-centos shells]# vim parameter.sh 
[root@VM-12-10-centos shells]# cat parameter.sh 
#!/bin/bash
echo '=====$n====='
echo $0
echo $1
echo $2
echo '=====$#====='
echo $#
echo '=====$*====='
echo $*
echo '=====$@====='
echo $@
[root@VM-12-10-centos shells]# ./parameter.sh x y z ab c
=====$n=====
./parameter.sh
x
y
=====$#=====
5
=====$*=====
x y z ab c
=====$@=====
x y z ab c

$?

$?:最后一次执行的命令的返回状态。

  • 如果这个变量的值为0,证明上一个命令正确执行;
  • 如果这个变量的值为非0(具体为何值,由命令自身决定),则证明上一个命令执行不正确。
[root@VM-12-10-centos shells]# ./parameter.sh 
=====$n=====
./parameter.sh


=====$#=====
0
=====$*=====

=====$@=====

[root@VM-12-10-centos shells]# echo $?
0

四、运算符

基本语法$((运算式))$[运算式]

例:计算(2+3)*4的值

[root@VM-12-10-centos shells]# S=$[(2+3)*4]
[root@VM-12-10-centos shells]# echo $S
20

五、条件判断

5.1 基本语法

  • test 条件
  • [ 条件 ],注:条件前后都要有空格

注:条件飞控即为true,[ x ]返回true,[ ]返回false。

5.2 常用判断条件

两个整数之间比较

  • -eq 等于(equal)
  • -ne不等于(not equal)
  • -lt小于(less than)
  • -le小于等于(less equal)
  • -gt大于(greater than)
  • -ge大于等于(greater equal)

注:如果是字符串之间的比较,用=判断相等;用!=判断不相等。

[root@VM-12-10-centos shells]# [ 1 -ge 2 ]
[root@VM-12-10-centos shells]# echo $?
1
[root@VM-12-10-centos shells]# [ 1 -lt 2 ]
[root@VM-12-10-centos shells]# echo $?
0

按照文件权限进行判断

  • -r有读的权限(read)
  • -w有写的权限(write)
  • -x有执行的权限(execute)
[root@VM-12-10-centos shells]# [ -w parameter.sh ]
[root@VM-12-10-centos shells]# echo $?
0

按照文件类型进行判断

  • -e文件存在(existence)
  • -f文件存在并且是一个常规的文件(file)
  • -d文件存在并且是一个目录(directory)
[root@VM-12-10-centos shells]# [ -e /home/shells ]
[root@VM-12-10-centos shells]# echo $?
0
[root@VM-12-10-centos shells]# [ -e ./parameter.sh ]
[root@VM-12-10-centos shells]# echo $?
0
[root@VM-12-10-centos shells]# [ -d /home/shells ]
[root@VM-12-10-centos shells]# echo $?
127

多条件判断

  • &&表示前一条命令执行成功时,才执行后一条命令;
  • ||表示上一条命令执行失败时,才执行下一条命令。
[root@VM-12-10-centos shells]# [ 1 -eq 2 ] && echo TRUE || echo FALSE
FALSE
[root@VM-12-10-centos shells]# [ 1 -lt 2 ] && echo TRUE || echo FALSE
TRUE

六、流程控制

6.1 if

基本语法

  1. 单分支

    if [ 条件判断式 ];then
    	程序
    fi
    

    if [ 条件判断式 ]
    then
    	程序
    fi
    
  2. 多分支

    if [ 条件判断式 ]
    then
    	程序
    elif [ 条件判断式 ]
    then
    	程序
    else
    	程序
    fi
    

注意:

  • [ 条件判断式 ]中括号和条件判断式之间必须有空格
  • if后要有空格

例:输入一个数字,如果是0,则输出yes;反之,则输出no。

[root@VM-12-10-centos shells]# vim if.sh
[root@VM-12-10-centos shells]# cat if.sh 
#!/bin/bash

if [ $1 -eq 0 ]
then
        echo "yes"
else
        echo "no"
fi
[root@VM-12-10-centos shells]# chmod u+x if.sh 
[root@VM-12-10-centos shells]# ./if.sh 
./if.sh: line 3: [: -eq: unary operator expected
no
[root@VM-12-10-centos shells]# ./if.sh 0
yes
[root@VM-12-10-centos shells]# ./if.sh 1
no

6.2 case

基本语法

case $变量名 in
"值1")
	如果变量的值等于值1,则执行程序1
;;
"值2")
	如果变量的值等于值2,则执行程序2
;;
	...省略其它分支...
*)
	如果变量的值都不是以上的值,则执行此程序
;;
esac

注意:

  • case行尾必须为单词in,每一个模式匹配必须以右括号)结束。
  • 双分号;;表示命令序列结束,相当于java中的break。
  • 最后的*表示默认模式,相当于java中的default。

例:输入一个数字,如果是1,则输出one;如果是2,则输出two;如果是其它,则输出other。

[root@VM-12-10-centos shells]# vim case.sh
[root@VM-12-10-centos shells]# cat case.sh 
#!/bin/bash

case $1 in
"1")
        echo "one"
;;
"2")
        echo "two"
;;
*)
        echo "other"
;;
esac

[root@VM-12-10-centos shells]# chmod 777 case.sh 
[root@VM-12-10-centos shells]# ./case.sh 1
one
[root@VM-12-10-centos shells]# ./case.sh 2
two
[root@VM-12-10-centos shells]# ./case.sh 3
other

6.3 for

  • 基本语法1

    for (( 初始值;循环控制条件;变量变化 ))
    do
    	程序
    done
    
    
  • 基本语法2

    for 变量 in 值1 值2 值3...
    do
    	程序
    done
    

例:求1-100的和。

[root@VM-12-10-centos shells]# vim for_1.sh 
[root@VM-12-10-centos shells]# cat for_1.sh 
#!/bin/bash

sum=0
for((i=0;i<=100;i++))
do
        sum=$[$sum+$i]
done
echo "sum[1-100] = "$sum
[root@VM-12-10-centos shells]# chmod 777 for_1.sh 
[root@VM-12-10-centos shells]# ./for_1.sh 
sum[1-100] = 5050

例:打印所有输入参数。

[root@VM-12-10-centos shells]# vim for_2.sh
[root@VM-12-10-centos shells]# cat for_2.sh 
#!/bin/bash

for i in a b c
do
        echo "输出:$i"
done
[root@VM-12-10-centos shells]# chmod 777 for_2.sh 
[root@VM-12-10-centos shells]# ./for_2.sh 
输出:a
输出:b
输出:c

$*$@的区别

  • $*$@都表示传递给函数或脚本的所有参数,不被双引号""包含时,都以$1 $2 ...$n的形式输出所有参数。

    [root@VM-12-10-centos shells]# vim for_3.sh 
    [root@VM-12-10-centos shells]# cat for_3.sh 
    #!/bin/bash
    
    echo '=====$*====='
    for i in $*
    do
            echo "输出:$i"
    done
    
    echo '=====$@====='
    for j in $@
    do
            echo "输出:$j"
    done
    [root@VM-12-10-centos shells]# chmod 777 for_3.sh 
    [root@VM-12-10-centos shells]# ./for_3.sh a b c
    =====$*=====
    输出:a
    输出:b
    输出:c
    =====$@=====
    输出:a
    输出:b
    输出:c
    
    
  • 当两者被双引号""包含时,$*会将所有的参数作为一个整体,以$1 $2 ...$n的形式输出所有参数;$@会将各个参数分开,以$1 $2$n的形式输出所有参数。

    [root@VM-12-10-centos shells]# vim for_4.sh 
    [root@VM-12-10-centos shells]# cat for_4.sh 
    #!/bin/bash
    
    echo '=====$*====='
    for i in  "$*"
    # $*中的所有参数看成是一个整体,所以这个 for 循环只会循环一次
    do
            echo "输出:$i"
    done
    
    echo '=====$@====='
    for j in "$@"
    # $@中的每个参数都看成是独立的,所以"$@"中有几个参数,就会循环几次
    do
            echo "输出:$j"
    done
    [root@VM-12-10-centos shells]# chmod 777 for_4.sh
    [root@VM-12-10-centos shells]# ./for_4.sh a b c
    =====$*=====
    输出:a b c
    =====$@=====
    输出:a
    输出:b
    输出:c
    

6.4 while

基本语法

while [ 条件判断式 ]
do
	程序
done

例:求1-100的和。

[root@VM-12-10-centos shells]# vim while.sh
[root@VM-12-10-centos shells]# cat while.sh 
#!/bin/bash

sum=0
i=1
while [ $i -le 100 ]
do
        sum=$[$sum+$i]
        i=$[$i+1]
done
echo "sum[1-100] = $sum"
[root@VM-12-10-centos shells]# chmod 777 while.sh 
[root@VM-12-10-centos shells]# ./while.sh 
sum[1-100] = 5050

七、read读取控制台输入

7.1 基本语法

read (选项) (参数)

  1. 选项:
    • -p:指定读取值时的提示符;
    • -t:指定读取值时等待的时间(秒),如果-t不加表示一直等待。
  2. 参数:变量,指定读取值的变量名。
[root@VM-12-10-centos shells]# vim read.sh
[root@VM-12-10-centos shells]# cat read.sh 
#!/bin/bash

read -t 7 -p "请在7秒内输入x变量的值:" x
echo $x
[root@VM-12-10-centos shells]# chmod 777 read.sh
[root@VM-12-10-centos shells]# ./read.sh
请在7秒内输入x变量的值:123
123

八、函数

8.1 系统函数

basename

基本语法

basename [string/pathname] [suffix]:basename命令会删掉所有的前缀包括最后一个/字符,然后将字符串显示出来

  • basename可以理解为取路径里的文件名称。
  • suffix为后缀,如果suffix被指定了,basename会将pathname或string中的suffix去掉。

例:截取/home/shells/test.sh路径的文件名称。

[root@VM-12-10-centos shells]# basename /home/shells/test.sh 
test.sh
[root@VM-12-10-centos shells]# basename /home/shells/test.sh .sh
test

dirname

基本语法

dirname 文件绝对路径:从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分)。

dirname可以理解为取文件路径的绝对路径名称。

例:截取/home/shells/test.sh文件的路径。

[root@VM-12-10-centos shells]# dirname /home/shells/test.sh 
/home/shells

自定义函数

基本语法

[function] funname[()]
{
	Action;
	[return int;]
}
  • 必须在调用函数之前,先声明函数,shell脚本是逐行运行。不会像其它语言一样先编译。
  • 函数返回值,只能通过$?系统变量获得,可以显示加return返回;如果不佳,将以最后一条命令运行结果,作为返回值。return后跟数值n(0-255)。

例:计算两个输入参数的和。

[root@VM-12-10-centos shells]# vim fun.sh
[root@VM-12-10-centos shells]# cat fun.sh 
#!/bin/bash

function sum()
{
        a=0
        a=$[$1+$2]
        echo "$a"
}

read -p "请输入第一个数字:" x;
read -p "请输入第二个数字:" y;
sum $x $y;
[root@VM-12-10-centos shells]# chmod 777 fun.sh 
[root@VM-12-10-centos shells]# ./fun.sh 
请输入第一个数字:2
请输入第二个数字:3
5

九、正则表达式

正则表达式使用单个字符串来描述、匹配一系列符合某个语法规则的字符串。在很多文本编辑器中,正则表达式通常被用来检索、替换符合某个格式的文本。

在Linux中,grep、sed、awk等文本处理工具都支持通过正则表达式进行模式匹配。

9.1 常规匹配

一串不包含特殊字符的正则表达式匹配指定的字符串。

例:匹配所有包含spool的行。

[root@VM-12-10-centos shells]# cat /etc/passwd | grep spool
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin

9.2 常用特殊字符

特殊字符:^

^匹配一行的开头。

例:匹配所有以root开头的行。

[root@VM-12-10-centos shells]# cat /etc/passwd | grep ^root
root:x:0:0:root:/root:/bin/bash

特殊字符:$

$匹配一行的结束。

例:匹配所有以lt结尾的行。

[root@VM-12-10-centos shells]# cat /etc/passwd | grep lt$
halt:x:7:0:halt:/sbin:/sbin/halt

特殊字符:.

.匹配一个任意的字符。

例:匹配含r和t且两者之间有且值存在两个字符的行。

[root@VM-12-10-centos shells]# cat /etc/passwd | grep r..t
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin

特殊字符:*

*表示匹配上一个字符0次或多次。不单独使用,与上一个字符连用。

例:匹配含ro和t且ro在前,t在后的所有行。

[root@VM-12-10-centos shells]# cat /etc/passwd | grep ro*t
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin

字符区间:[]

[]表示匹配某个范围内的一个字符。例:

  • [6,8]:匹配6或8
  • [0-9]:匹配一个0-9的数字
  • [0-9]*:匹配任意长度的数字字符串
  • [a-z]:匹配一个a-z之间的字符
  • [a-z]*:匹配任意长度的字符字符串
  • [a-c,e-g]:匹配a-c或e-g之间的任意字符
[root@VM-12-10-centos shells]# cat /etc/passwd | grep r[a,b,c]*t
operator:x:11:0:operator:/root:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin

特殊字符:\

\表示转义,并不会单独使用。由于所有特殊字符都有其特定匹配模式,当需要匹配某一特殊字符本身时(例:需查找所有包含$的行),就会很困难,此时需要将转义字符和特殊字符连用**(需要使用单引号将表达式引起来)**,来表示特殊字符本身。

例:查找所有包含:/bin的行。

[root@VM-12-10-centos shells]# cat /etc/passwd | grep ':\/bin'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
syslog:x:996:994::/home/syslog:/bin/false
lighthouse:x:1000:1000::/home/lighthouse:/bin/bash
postgres:x:26:26:PostgreSQL Server:/var/lib/pgsql:/bin/bash
mysql:x:1001:1001::/home/mysql:/bin/bash

十、文本处理工具

10.1 cut

cut就是,在文件中负责剪切数据使用的。cut命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段输出。

基本语法

cut [选项参数] filename

默认分隔符是制表符

选项参数说明

  • -f:列号,提取第几列。
  • -d:分隔符,按照指定分隔符分隔列,默认就是制表符\t
  • -c:按字符进行切割后加n,表示取第几列。例:按字符切割后取第一列-c 1

例:切割cut.txt文件第一列,切割cut.txt文件第二、三列。

[root@VM-12-10-centos shells]# vim cut.txt 
[root@VM-12-10-centos shells]# cat cut.txt 
文本 分 制
处理 隔 表
工具 符 符
[root@VM-12-10-centos shells]# cut -d " " -f 1 cut.txt 
文本
处理
工具
[root@VM-12-10-centos shells]# cut -d " " -f 2,3 cut.txt 
分 制
隔 表
符 符

例:在cut.txt文件中切割出处理

[root@VM-12-10-centos shells]# cat cut.txt | grep 处理 | cut -d " " -f 1
处理

例:获取系统PATH变量值第二个:开始后的所有路径。

[root@VM-12-10-centos shells]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/usr/local/mysql/bin
[root@VM-12-10-centos shells]# echo $PATH | cut -d ":" -f 3-
/usr/sbin:/usr/bin:/root/bin:/usr/local/mysql/bin

10.2 awk

awk:一个强大的文本分析工具,把文件逐行读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理。

基本语法

awk [选项参数] '/pattern/{action} /pattern/{action}...' filename

  • pattern:表示awk在数据中查找的内容,就是匹配模式。
  • action:在找到匹配内容时所执行的一系列命令。

选项参数说明

  • -F:指定输入文件分隔符。
  • -v:赋值一个用户定义变量。

awk的内置变量

  • FILENAME:文件名。
  • NR:已读的记录数(行号)。
  • NF:浏览记录的域的个数(切割后列的个数)。
# 数据准备
[root@VM-12-10-centos shells]# sudo cp /etc/passwd ./
# passwd数据的含义:
# 用户名:密码(加密过后的):用户 id:组 id:注释:用户家目录:shell 解析器

# 搜索passwd文件以root关键字开头的所有行,并输出该行的第7列
[root@VM-12-10-centos shells]# awk -F : '/^root/{print $7}' passwd
/bin/bash

# 搜索passwd文件以root关键字开头的所有行,并输出该行的第1列和第7列,中间以,号分割
[root@VM-12-10-centos shells]# awk -F : '/^root/{print $1","$7}' passwd
root,/bin/bash
# 只有匹配了pattern的行才会执行action

# 只显示/etc/passwd中以r开头第一列和第七列,以逗号分割,且在所有行前面添加列名user,shell在最后一行添加xxx,/bin/xxxx
[root@VM-12-10-centos shells]# awk -F : 'BEGIN{print "user,shell"} /^r/{print $1","$7} END{print "xxx,/bin/xxxx"}' passwd
user,shell
root,/bin/bash
rpc,/sbin/nologin
xxx,/bin/xxxx
# BEGIN在所有数据读取行之前执行
# END在所有数据执行之后执行

# 将passwd文件中以r开头的用户id增加数值1并输出
[root@VM-12-10-centos shells]# awk -v i=1 -F : '/^r/{print $3+i}' passwd
1
33

# 统计passwd文件名,每行的行号,每行的列数
[root@VM-12-10-centos shells]# awk -F : '{print "filename:" FILENAME ",linenum:" NR ",col:" NF}' passwd
filename:passwd,linenum:1,col:7
filename:passwd,linenum:2,col:7
filename:passwd,linenum:3,col:7
filename:passwd,linenum:4,col:7
# ......

# 查询ifconfig命令输出结果中的空行所在的行号
[root@VM-12-10-centos shells]# ifconfig | awk '/^$/{print NR}'
9
18

# 切割ip
[root@VM-12-10-centos shells]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.12.10  netmask 255.255.252.0  broadcast 10.0.15.255
        inet6 fe80::5054:ff:fe2b:8e1e  prefixlen 64  scopeid 0x20<link>
				# ......
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@VM-12-10-centos shells]# ifconfig eth0 | awk '/netmask/ {print $2}'
10.0.12.10

十一、应用案例

归档文件

实现一个每天对指定目录归档备份的脚本,输入一个目录名称(末尾不带/),将目录下所有文件按天归档保存,并将归档日期附加在归档文件名上,放在/home/bak下。

使用归档命令tar,后面可以加上-c选项表示归档,加上-z选项表示同时进行压缩,得到的文件后缀名为.tar.gz

[root@VM-12-10-centos shells]# vim bak.sh 
[root@VM-12-10-centos shells]# cat bak.sh 
#!/bin/bash

# 判断输入参数个数是否为1
if [ $# -ne 1 ]
then 
        echo "参数个数错误!应输入一个参数,作为归档目录名。"
        exit;
fi

# 从参数中获取目录名称
if [ -d $1 ]
then 
        echo
else
        echo
        echo "目录不存在!"
        echo
        exit
fi

DIR_NAME=$(basename $1)
DIR_PATH=$(cd $(dirname $1); pwd)

# 获取当前日期
DATE=$(date +%Y-%m-%d)

# 定义生成的归档文件名称
FILE=bak_${DIR_NAME}_$DATE.tar.gz
BAK_DIR=/home/bak
# 判断备份路径是否存在
if [ ! -d "$BAK_DIR" ];then
        echo
        echo "备份目录不存在"
        mkdir $BAK_DIR
        echo
else
        echo
        echo "备份目录已存在!"
        echo
fi
DEST=${BAK_DIR}/$FILE

# 开始归档目录文件
echo "开始归档..."
echo
# 加-P打包屏蔽提示 tar: 从成员名中删除开头的“/”
tar -czf $DEST $DIR_PATH/$DIR_NAME

if [ $? -eq 0 ]
then 
        echo
        echo "归档成功!"
        echo "归档文件:$DEST"
        echo
else
        echo "归档失败!"
        echo
fi

exit

[root@VM-12-10-centos shells]# ./bak.sh /home/shells/


备份目录已存在!

开始归档...

tar: 从成员名中删除开头的“/”

归档成功!
归档文件:/home/bak/bak_shells_2023-03-08.tar.gz

[root@VM-12-10-centos shells]#

发送消息

利用Linux自带的mesg和write工具,向其它用户发送消息。

实现一个向某个用户快速发送消息的脚本,输入用户名作为第一个参数,后面直接跟要发送的消息。脚本需要检测用户是否登录在系统中、是否打开消息功能,以及当前发送消息是否为空。

[root@VM-12-10-centos shells]# vim message.sh 
[root@VM-12-10-centos shells]# cat message.sh 
#!/bin/bash 

login_user=$(who | grep -i -m 1 $1 | awk '{print $1}') 

if [ -z $login_user ] 
then
        echo "$1 不在线!" 
        echo "脚本退出.." 
        exit 
fi

is_allowed=$(who -T | grep -i -m 1 $1 | awk '{print $2}')

if [ $is_allowed != "+" ] 
then
        echo "$1 没有开启消息功能" 
        echo "脚本退出.." 
        exit 
fi

if [ -z $2 ] 
then
        echo "没有消息发出" 
        echo "脚本退出.." 
        exit 
fi

whole_msg=$(echo $* | cut -d " " -f 2- ) 

user_terminal=$(who | grep -i -m 1 $1 | awk '{print $2}')

echo $whole_msg | write $login_user $user_terminal

if [ $? != 0 ] 
then
        echo "发送失败!" 
else
        echo "发送成功!" 
fi

[root@VM-12-10-centos shells]# ./message.sh mysql
mysql 不在线!
脚本退出..
[root@VM-12-10-centos shells]# ./message.sh root hello

Message from root@VM-12-10-centos on pts/0 at 21:24 ...
hello
EOF
发送成功!

标签:10,12,centos,shells,VM,笔记,学习,Shell,root
From: https://blog.csdn.net/weixin_45563821/article/details/140252678

相关文章

  • 【2024最新】零基础如何学习挖漏洞?看这篇就够了(超详细)
    文章目录前言什么是漏洞挖掘学习漏洞挖掘的正确顺序漏洞挖掘需要具备的知识漏洞挖掘需要做什么有关漏洞挖掘的其他想法漏洞的复杂性团队工作写在最后==如何入门学习网络安全【黑客】==【----帮助网安学习,以下所有学习资料文末免费领取!----】大纲学习教程面试刷题资料......
  • 新时代【机器学习】与【Pycharm】:【随机数据生成】与智能【股票市场分析】
    目录第一步:准备工作1.1安装必要的库小李的理解:1.2导入库小李的理解:第二步:生成和准备数据2.1生成随机股票数据小李的理解:2.2数据探索与可视化小李的理解:2.3数据处理小李的理解:2.4选择特征和标签小李的理解:第三步:拆分数据集小李的理解:第四步:训练决策树模......
  • 【狂神说Java】系列学习笔记01——MarkDown语法
    #MarkDown学习本文为B站老师秦疆【狂神说Java】系列,课堂学习笔记,主要联练习的是MarkDown的使用方法,老师的博客链接我没找到,广告1.标题+加粗2级3级4级5级6级最多七级标题Helloworld!Helloworld!Helloworld!Helloworld!引用-沐风6标题一级标题(#+空格)二......
  • Dubbo源码学习
    学习Dubbo框架与手写模拟相关内容一、存在的意义Dubbo:解决分布式系统的复杂性,实现服务治理(使服务之间的调用变的简单)和自动注册与发现,简化服务调用。二、调用过程Dubbo的使用接口代表一种服务,对应不同的实现,使服务之间的依赖变的简单。服务消费者通过ClassPassXmlApplicati......
  • linux学习之登录密码(ssh/telnet)
    在Linux系统中,用户登录密码是用于安全验证用户身份的一种方式。登录密码通常是加密后存储在系统的/etc/shadow文件中。如果您想要获取Linux系统中用户的登录密码,这通常是不可能的,因为密码是经过加密处理的,而且出于安全考虑,没有直接的方式可以获取它们的明文形式。/etc/passwd......
  • redis学习(007 实战:黑马点评:登录)
    黑马程序员Redis入门到实战教程,深度透析redis底层原理+redis分布式锁+企业解决方案+黑马点评实战项目总时长42:48:00共175P此文章包含第25p-第p34的内容文章目录短信登录功能session共享问题短信登录功能接口编写这里是Result的封装过滤器在......
  • PLC CODESYS 学习:入门第一步(辅助资料)
    CodeSys平台的基本功能和编程技能掌握:>>PDF书籍:《CODESYS-V4-基础编程指南完整版.pdf》《开放式控制系统编程技术基于IEC 61131-3国际标准.pdf》>>中文在线帮助手册:《CODESYSDevelopmentSystem》链接:CODESYSOnlineHelp>>错误查找:在帮助手册上查找SMC_ERROR(ENUM)可......
  • powershell获取更多关于 Windows 操作系统的详细信息,可以考虑扩展脚本来获取其他属性
    powershell获取更多关于Windows操作系统的详细信息,可以考虑扩展脚本来获取其他属性。例如,你可以使用以下脚本来获取更多注册表键值的信息:powershellCopyCode#获取更多关于WindowsNT的信息Get-ItemProperty-Path"HKLM:\SOFTWARE\Microsoft\WindowsNT\CurrentVersion"......
  • C语言学习笔记(02)——关键字概念
    sizeof编译器给我们查看内存空间容量的一个工具不存在函数实现,在任何情况下都可以使用inta:printf("theais%d\n",sizeof(a));printf("theais%lu\n",sizeof(a)); //最好使用%lu打印,因为sizeof默认返回的是unsignedlong类型的>>>4char:硬件处理的最小单位;8bit=1B,8bi......
  • 实训第一天笔记
    图片里是今天学习的主要内容:今天学习了很多东西,有新的命令也有旧的命令,故障也有出现,最后访问到想要的页面了。下面是操作的主要命令操作:  1 rm-rf/etc/yum.repos.d/*  2 vi/etc/yum.repos.d/dd.repo  5 mount-a  8 yum-yinstallbash-co......