SHELL/SSH基础知识(入门篇)-包含 shell 脚本语言的基本用法、 shell 脚本语言的基本用法、流程控制、函数 function、其它脚本相关工具、数组 array(欢迎留言交流)

目录

1 shell 脚本语言的基本用法

1.1 shell 脚本注释规范

1.1.1 shell 脚本注释规范

1.1.2 执行(5种)

1.1.3 在远程主机运行本地脚本

1.1.4 检查shell脚本

1.2 shell变量

1.2.1 Shell中变量命名法则

1.2.2 变量赋值与引用

1.2.3 环境变量的查看设置和删除

1.2.4 只读变量

1.2.5 位置变量

1.2.6 退出状态码变量

1.2.7 展开命令行

1.3 退出状态码变量

1.4 展开命令行

1.5 脚本安全和 set

1.6 格式化输出 printf命令

1.7 echo 命令

1.8 算术运算

1.9 短路运算

1.10 条件测试命令

1.10.1 条件测试命令

1.10.2 常用选项:文件判断相关

1.10.3 常用选项:字符串判断相关

1.10.4 常用选项:数学相关

1.10.5 变量测试

1.10.6 字符串测试

1.11 关于 () 和 {}

1.12 组合测试条件

2 bash shell 的配置文件

2.1 shell登录两种方式分类

2.2 按功能划分分类

2.3 编辑配置文件生效

2.4 Bash 退出任务

3 流程控制

3.1 选择执行 if 语句

3.2 条件判断 case 语句

3.3 循环的命令 for命令

3.3.1 方法 一

3.3.2 方法二

3.4 循环 while

3.4.1 无限循环

3.4.2 while 特殊用法 while read

3.4.3 循环 until(反的while)

3.5 循环与菜单 select

3.6 控制语句

3.6.1 循环控制语句 continue

3.6.2 循环控制语句 break

3.6.3 循环控制 shift 命令

4 函数 function

4.1 函数介绍

4.2.1 定义函数

4.2.2 查看函数

4.2.3 删除函数

4.3 函数调用

4.3.2 在脚本中定义及使用函数

4.4 函数返回值

4.5 环境函数

4.6 函数递归

5 其它脚本相关工具

5.1 信号捕捉 trap

5.2 创建临时文件 mktemp

6 数组 array

6.3 数组赋值

6.4 显示所有数组

6.5 引用数组

6.6 删除数组

6.8 关联数组

7 字符串处理

7.1 字符串切片

shell 脚本案例

1 显示指标(括CPU型号,内存大小,硬盘大小,操作系统版本)

2.编写脚本 backup.sh,可实现每日将 /etc/ 目录备份到 /backup/etcYYYY-mm-dd中

3.编写脚本 disk.sh,显示当前硬盘分区中空间利用率最大的值

4.编写脚本 links.sh,显示正连接本主机的每个远程主机的IPv4地址和连接数,并按连接数从大到小 排 序


1 shell 脚本语言的基本用法

一个shell脚本文件中主要包含以下内容

  • 各种系统命令的组合

  • 数据存储:变量、数组

  • 表达式:a + b

  • 控制语句:if

格式要求:首行shebang机制(#!)

#!/bin/bash 
#!/usr/bin/python
#!/usr/bin/perl 
#!/usr/bin/ruby
#!/usr/bin/lua

有的时候被启用有的时候不被启用

1.1 shell 脚本注释规范

一般要注明作者,创建(修改)时间,文件名,版本号,该程序的功能及作用,目地,版权信息,作者联系 方式等

1.1.1 shell 脚本注释规范

[root@bogon test.dir]# cat ~/.vimar
cat: /root/.vimar: No such file or directory
[root@bogon test.dir]# cat ~/.vimrc 
set nu
set ts=4
autocmd BufNewFile *.sh exec ":call SetTitle()"
func SetTitle()
    if expand("%:e") == 'sh'
       call setline(1,"#!/bin/bash")
       call setline(2,"#")
       call setline(3,"#****************************************************")
       call setline(4,"#Author:           caojidong")
       call setline(5,"#QQ:               1549396190")
       call setline(6,"#Date:             ".strftime("%Y-%m-%d"))
       call setline(7,"#FileName:         ".expand("%"))
       call setline(8,"#cell-phone number:               13739548267")
       call setline(9,"#Description:      test")
       call setline(10,"#Copyright(C):     ".strftime("%Y")." All right")
       call setline(11,"#***************************************************")
​
   endif
endfunc
​

1.1.2 执行(5种)

[root@bogon test.dir]# ./1.test.sh  #./sh,就是会去使用脚本中声明的第一行的解释器来解释脚本的内容
hello word
caojidong
[root@bogon test.dir]# . 1.test.sh 
hello word                         #在当前进程中执行
caojidong
[root@bogon test.dir]# bash 1.test.sh 
hello word
caojidong
[root@bogon test.dir]# sh 1.test.sh  #使用sh install.sh 如果这个脚本文件当前用户没有执行的权限也是能够执行的
hello word
caojidong
[root@bogon test.dir]# /tmp/test.dir/1.test.sh 
hello word
caojidong
​
借鉴别人写的挺好的文章:
https://blog.csdn.net/weixin_37569048/article/details/97764626?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_title~default-1.no_search_link&spm=1001.2101.3001.4242
————————————————
版权声明:本文为CSDN博主「如梦@_@」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43726471/article/details/120800757

瞬间启动子shell :用括号表示。

echo $BASHPID;( echo $BASHPID; sleep 300; )
​

1.1.3 在远程主机运行本地脚本

本地执行远程脚本

[root@rocky86 ~]# curl http://10.0.0.157/test.sh -s | bash
hello, world
Hello, world!
[root@rocky86 ~]# curl http://10.0.0.157/test.sh 2>/dev/null | bash
hello, world
Hello, world!
[root@rocky86 ~]# wget -qO - http://10.0.0.157/test.sh | bash
hello, world
Hello, world!

curl和wget的区别和使用

1.下载文件

curl -O http://man.linuxde.net/text.iso                    #O大写,不用O只是打印内容不会下载
wget http://www.linuxde.net/text.iso                       #不用参数,直接下载文件

2.下载文件并重命名

curl -o rename.iso http://man.linuxde.net/text.iso         #o小写
wget -O rename.zip http://www.linuxde.net/text.iso         #O大写

3.断点续传

curl -O -C -URL http://man.linuxde.net/text.iso            #C大写
wget -c http://www.linuxde.net/text.iso                    #c小写

4.限速下载

curl --limit-rate 50k -O http://man.linuxde.net/text.iso
wget --limit-rate=50k http://www.linuxde.net/text.iso

5.显示响应头部信息

curl -I http://man.linuxde.net/text.iso
wget --server-response http://www.linuxde.net/test.iso

6.wget利器--打包下载网站

wget --mirror -p --convert-links -P /var/www/html http://man.linuxde.net/

在远程主机运行(本地脚本)

[root@rocky86 ~]# cat test2.sh
#!/bin/bash
#
#****************************************************
#Author: jose
#QQ: 123456
#Date: 2022-08-16
#FileName: test2.sh
#URL: http://www.magedu.com
#Description: test
#Copyright(C): 2022 All right
#***************************************************
hostname -I
#本地执行
[root@rocky86 ~]# bash test2.sh
10.0.0.150
#远程主机上执行
[root@rocky86 ~]# ssh [email protected] /bin/bash < test2.sh
[email protected]'s password:
10.0.0.157

1.1.4 检查shell脚本

  • 语法错误:会导致后续的命令不继续执行,可以用 bash -n 检查错误,提示的出错行数不一定是准 确的

  • 命令错误:默认后续的命令还会继续执行,用 bash -n 无法检查出来 ,可以使用 bash -x 进行观察

  • 逻辑错误:只能使用 bash -x 进行观察

此选项只能检测脚本中的语法错误,不能检测命令错误,也不会执行脚本

bash -n test.sh #bash -n 脚本名称
​

逐行输出命令,并输出执行结果

bash -x test.sh  #bash -x 脚本名称

1.2 shell变量

变量数据类型:

字符
数值:整型、浮点型,bash 不支持浮点数
布尔
指针
结构体

静态和动态语言

静态编译语言:使用变量前,先声明变量类型,之后类型不能改变,在编译时检查,如:java,c 
​
动态编译语言:不用事先声明,可随时改变类型,如:bash,Python

强类型和弱类型语言

强类型语言:不同类型数据操作,必须经过强制转换才同一类型才能运算,如: java , c# ,
python 
弱类型语言:语言的运行时会隐式做数据类型转换。无须指定类型,默认均为字符型;参与运算会
自动进行隐式类型转换;变量无须事先定义可直接调用,如:bash ,php,javascript
​

1.2.1 Shell中变量命名法则

命名要求

  • 区分大小写

  • 不能使程序中的保留字和内置变量:如:if, for

  • 只能使用数字、字母及下划线,且不能以数字开头,注意:不支持短横线 “ - ”,和主机名相反

#主机名只允许含ascii字符里的数字和字母,-和. 。其余的都不允许。

运行shell时,会同时存在三种变量:

变量的生效范围等标准划分变量类型

  1、局部变量:局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。

【小写:局部变量小写 函数名小写

大驼峰StudentFirstName,由多个单词组成,且每个单词的首字母是大写,其它小写

小驼峰studentFirstName ,由多个单词组成,第一个单词的首字母小写,后续每个单词的首字母 是 大写,其它小写】

  2、环境变量:所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行,必要的时候shell脚本也可以定义环境变量。

【大写】

  3、shell变量:shell变量是由shell程序设置的特殊变量,shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行。

1.2.2 变量赋值与引用

1.2.2.1 赋值

value 可以是以下多种形式

name='root' #直接字串
name="$USER" #变量引用
name=`COMMAND` #命令引用
name=$(COMMAND) #命令引用

注意:变量赋值是临时生效,当退出终端后,变量会自动删除,无法持久保存,脚本中的变量会随着脚 本结束,也会自动删除

#变量保存、变量永久保存方法、变量永久保存路径

在/etc/profile文件中添加变量【对所有用户生效(永久的)】
[root@bogon ~]# vim /etc/profile
注:修改文件后要想马上生效还要运行$ source /home/guok/.bash_profile不然只能在下次重进此用户时生效。
​

1.2.2.2 引用

$name
${name}

弱引用和强引用 "$name" 弱引用,其中的变量引用会被替换为变量值 '$name' 强引用,其中的变量引用不会被替换为变量值,而保持原字符串

变量的间接赋值和引用(变量和变量引用)

[root@centos8 ~]#TITLE=cto
[root@centos8 ~]#NAME=wang
[root@centos8 ~]#TITLE=$NAME
[root@centos8 ~]#echo $NAME
wang
[root@centos8 ~]#echo $TITLE
wang
[root@centos8 ~]#NAME=mage
[root@centos8 ~]#echo $NAME
mage
[root@centos8 ~]#echo $TITLE
wang
​

变量追加值

[root@centos8 ~]#TITLE=CTO
[root@centos8 ~]#TITLE+=:wang
[root@centos8 ~]#echo $TITLE
CTO:wang

利用变量实现动态命令

[root@centos8 ~]#CMD=hostname
[root@centos8 ~]#$CMD
centos8.magedu.com
​

1.2.3 环境变量的查看设置和删除

定义bash环境的用户文件是:.bashrc &bash_profile

使用echo命令查看单个环境变量。例如:

root@bogon ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

使用env查看所有环境变量。例如:

[root@bogon ~]# env

查看指定进程的环境变量

cat /proc/$PID/environ #新指定的不输出

export命令定义变量

使用set查看所有本地定义的环境变量。

unset可以删除指定的环境变量。

[root@bogon test.dir]# export mage="66666666handsome"
[root@bogon test.dir]# set | grep mage
_=mage
mage=66666666handsome
[root@bogon test.dir]# unset mage
[root@bogon test.dir]# echo "$mage"

变量赋值:

#声明并赋值
export name=VALUE
declare -x name=VALUE
#或者分两步实现
name=VALUE
export name
​

declare 声明变量用法:

declare -x 声明环境变量export
declare -r 声明只读变量readonly
declare -i 声明整数int

bash内建的环境变量

PATH
SHELL
USER
UID
HOME
PWD
SHLVL #shell的嵌套层数,即深度
LANG
MAIL
HOSTNAME
HISTSIZE
_   #下划线,表示前一命令的最后一个参数
​

1.2.4 只读变量

只读变量:只能声明定义,但后续不能修改和删除,即常量 声明只读变量:

readonly name
declare -r name
​
readonly [-p]
declare -r
​
[root@centos8 ~]#readonly PI=3.14159
[root@centos8 ~]#echo $PI
3.14159
[root@centos8 ~]#PI=3.14
-bash: PI: readonly variable
[root@centos8 ~]#unset PI
-bash: unset: PI: cannot unset: readonly variable
[root@centos8 ~]#echo $PI
3.14159
[root@centos8 ~]#exit
logout
Connection closed by foreign host.
Disconnected from remote host(10.0.0.8) at 14:27:04.
Type `help' to learn how to use Xshell prompt.
[c:\~]$ 
Reconnecting in 1 seconds. Press any key to exit local shell.
.
Connecting to 10.0.0.8:22...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.
WARNING! The remote SSH server rejected X11 forwarding request.
Last login: Wed Apr  1 13:51:28 2020 from 10.0.0.1
[root@centos8 ~]#echo $PI
[root@centos8 ~]#
​

1.2.5 位置变量

$1,$2,... #对应第1个、第2个等参数,shift [n]换位置
$0 #命令本身,包括路径
$* #传递给脚本的所有参数,全部参数合为一个字符串
$@ #传递给脚本的所有参数,每个参数为独立字符串
$# #传递给脚本的参数的个数
 #注意:$@ $* 只在被双引号包起来的时候才会有差异

清空所有位置变量

[root@centos8 ~]#cat /data/scripts/arg.sh 
#!/bin/bash
#
#****************************************************
#Author:           jose
#QQ:               123456
#Date:             2022-08-17
#FileName:         arg.sh
#URL:               http://www.magedu.com
#Description:       test
#Copyright(C):     2022 All right
#***************************************************
echo "1st arg is $1"
echo "2st arg is $2"
echo "3st arg is $3"
echo "10st arg is ${10}"
echo "11st arg is ${11}"
echo "The number of arg is $#"
echo "All args are $*"
echo "All args are $@"
echo "The scriptname is `basename $0`"
[root@centos8 ~]#bash /data/scripts/arg.sh {a..z}
1st arg is a
2st arg is b
3st arg is c
10st arg is j
11st arg is k
The number of arg is 26
All args are a b c d e f g h i j k l m n o p q r s t u v w x y z
All args are a b c d e f g h i j k l m n o p q r s t u v w x y z
The scriptname is arg.sh
​

范例:删库跑路之命令rm的安全实现

rm=/tmp/test.dir/2.rm.test.sh
[root@centos8 ~]#cat /data/scripts/rm.sh 
#!/bin/bash
WARNING_COLOR="echo -e \E[1;31m"
END="\E[0m"
DIR=/tmp/`date +%F_%H-%M-%S`
mkdir $DIR
mv  $*  $DIR
${WARNING_COLOR}Move $* to $DIR $END
[root@centos8 ~]#chmod a+x /data/scripts/rm.sh
[root@centos8 ~]#alias rm='/data/scripts/rm.sh' #添加别名
[root@centos8 ~]#touch {1..10}.txt
[root@centos8 ~]#rm *.txt
Move 10.txt 1.txt 2.txt 3.txt 4.txt 5.txt 6.txt 7.txt 8.txt 9.txt to /tmp/2020-
04-01_15-15-28 
​

范例:$*和$@的区别

[root@centos8 scripts]#cat f1.sh
#!/bin/bash
echo "f1.sh:all args are $@"
echo "f1.sh:all args are $*"
./file.sh "$*"
[root@centos8 scripts]#cat f2.sh
#!/bin/bash
echo "f2.sh:all args are $@"
echo "f2.sh:all args are $*"
./file.sh "$@"
[root@centos8 scripts]#cat file.sh
#!/bin/bash
echo "file.sh:1st arg is $1"
[root@centos8 scripts]#./f1.sh a b c
f1.sh:all args are a b c
f1.sh:all args are a b c
范例: 利用软链接实现同一个脚本不同功能
2.7.9 退出状态码变量
当我们浏览网页时,有时会看到下图所显示的数字,表示网页的错误信息,我们称为状态码,在shell脚
本中也有相似的技术表示程序执行的相应状态。
file.sh:1st arg is a b c
[root@centos8 scripts]#./f2.sh a b c
f2.sh:all args are a b c
f2.sh:all args are a b c
file.sh:1st arg is a
​

范例: 利用软链接实现同一个脚本不同功能

[root@centos8 ~]#cat test.sh 
#!/bin/bash
#********************************************************************
echo $0
[root@centos8 ~]#ln -s test.sh a.sh # a.sh 是连接文件(linkname)
[root@centos8 ~]#ln -s test.sh b.sh
[root@centos8 ~]#./a.sh
./a.sh
[root@centos8 ~]#./b.sh
./b.sh

1.2.6 退出状态码变量

进程执行后,将使用变量 $? 保存状态码的相关数字,不同的值反应成功或失败,$?取值范例 0-255

$?   #0代表成功,1-255代表失败
[root@centos8 ~]#curl -fs http://www.wangxiaochun.com >/dev/null
[root@centos8 ~]#echo $?
0
​

用户可以在脚本中使用以下命令自定义退出状态码

exit [n]

注意:

  • 脚本中一旦遇到exit命令,脚本会立即终止;终止退出状态取决于exit命令后面的数字

  • 如果exit后面无数字,终止退出状态取决于exit命令前面命令执行结果

  • 如果没有exit命令, 即未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一 条命令的状态码

1.2.7 展开命令行

展开命令执行顺序

把命令行分成单个命令词
展开别名
展开大括号的声明{}
展开波浪符声明 ~
命令替换$() 和 ``
再次把命令行分成命令词
展开文件通配符*、?、[abc]等等
准备I/0重导向 <、>
运行命令

防止扩展

\ #反斜线 会使随后的字符按原意解释
[root@centos8 ~]#echo Your cost: \$5.00 
Your cost: $5.00
[root@rocky8 ~]#echo "The book's price is \$10"
The book's price is $10

你可能感兴趣的:(正则表达式,centos,linux,运维,ssh)