shell编程初识

1. Shell概述,编程语言.

1.1 编程概述

应用广泛: Shell占据的Linux半壁江山.
企业要求:面试要求运维人员必会.

目标:
1.能够熟练书写超过多行的脚本:

    检查类:
        系统巡检,
        系统加固,

    优化:(检查,配置优化)
        系统优化(初始化)(第2阶段开头).
        ngx优化(第2阶段开头).
        tomcat优化(第2阶段开头).
        数据库优化

    安装类(安装,配置,启动)
        编译安装nginx
        yum安装/apt安装
        二进制
        ...
2. 总计完成书读写5000行脚本(读写).
3. 完成100个脚本书写

SRE运维核心基操:https://www.yuque.com/lidao996/sre/vc088y5l9zof946c?singleDoc#

Shell编程总结:https://www.processon.com/view/link/65653d90c9a10714d94d5a21

1.2 编程语言

1.2.1 编程语言分类

编程语言分类

说明

解析型:直接解析类

shell,python,php, 书写成文件后,可以通过对应的解释器直接运行。

编译型:需要编译后运行

C,C++,Java(maven),Golang. 下载好源代码,必须要进行编译生成可以运行的命令。

 

1.2.2 Shell编程语言必知必会

Shell命令解释器:bash编程.

常用命令解释器.

命令解释器

 

bash

目前应用最广泛一款命令解释器,红帽系列(默认),Debian,Ubuntu,BASH全称: Bourne-Again SHell

dash

一般debian/ubuntu系统默认的, 运行脚本推荐使用 bash 1.sh

csh,tcsh

一些unix系统使用

zsh

功能更多,支持更多的插件,可以更好看。

⚠shell脚本(.bash .sh),运行在ubuntu中的时候,不推荐使用sh 运行,推荐使用bash运行.

2. Shell环境准备

修改vimrc文件,达到控制vim创建,编辑文件的动作。

当前用户家目录下 ~/.vimrc (只对当前用户生效)

追加:/etc/vimrc (红帽系列) /etc/vim/vimrc(ubuntu debian)

# 1.文件追加如下内容   /etc/vimrc  (红帽系列)   /etc/vim/vimrc(ubuntu debian)

set ignorecase 
autocmd BufNewFile *.py,*.cc,*.sh,*.java,*.bash exec ":call SetTitle()"

func SetTitle()
if expand("%:e") =~ 'sh\|bash\|py'
call setline(1, "#!/bin/bash")
call setline(2,"##############################################################")
call setline(3, "# File Name:".expand("%"))
call setline(4, "# Version:V1.0")
call setline(5, "# Author:xk")
call setline(6, "# Organization: none")
call setline(7, "# Desc:")
call setline(8,"##############################################################")

endif
endfunc

# 2. 使用vim创建sh|bash|py文件
[root@ubuntu2204 /etc/vim]# vim /etc/vim/vimrc
[root@ubuntu2204 ~]# vim 1.sh
[root@ubuntu2204 ~]#  
[root@ubuntu2204 ~]# cat 1.sh
#!/bin/bash
##############################################################
# File Name:1.sh
# Version:V1.0
# Author:xk
# Organization: none
# Desc:
##############################################################
[root@ubuntu2204 ~]# 

[root@Kylin-V10-sp3 ~]# vim /etc/vimrc

set ignorecase #搜索的时候忽略大小写

配置shell脚本dockerfile docker-compose的vimrc模板

查看代码
 #写入到/etc/vimrc文件末尾

autocmd BufNewFile *.py,*.cc,*.sh,*.java,*.bash,Dockerfile,docker-compose.yml exec ":call SetTitle()"

func SetTitle()  
    if expand("%:e") =~ 'sh\|bash'  
        call setline(1,"#!/bin/bash")
        call setline(2, "##############################################################")  
        call setline(3, "# File Name: ".expand("%"))
        call setline(4, "# Version: V1.0")
        call setline(5, "# Author: lidao996")
        call setline(6, "# Organization: www.oldboyedu.com")
        call setline(7, "# Description:")
        call setline(8, "##############################################################")
        call setline(9, "")
    endif  
    if expand("%") == 'Dockerfile'  
        call setline(1, "#####################Dockerfile###############################")
        call setline(2, "##############################################################")  
        call setline(3, "# File Name: ".expand("%"))
        call setline(4, "# Version: V1.0")
        call setline(5, "# Author: lidao996")
        call setline(6, "# Organization: www.oldboyedu.com")
        call setline(7, "# Description:")
        call setline(8, "##############################################################")
        call setline(9, "")
        call setline(10, "FROM")
        call setline(11, "LABEL maintaniner='oldboy  lidao@oldboyedu.com' author=lidao996")
        call setline(12, "CMD []")
    endif  
    if expand("%") == 'docker-compose.yml'  
        call setline(1, "#####################docker-compose###########################")
        call setline(2, "##############################################################")  
        call setline(3, "# File Name: ".expand("%"))
        call setline(4, "# Version: V1.0")
        call setline(5, "# Author: lidao996")
        call setline(6, "# Organization: www.oldboyedu.com")
        call setline(7, "# Description:")
        call setline(8, "##############################################################")
        call setline(9, "")
        call setline(10, "version: '3.3'")
        call setline(11, "services:")
        call setline(12, "volumes:")
    endif  
endfunc

 

3. Shell脚本执行方式

3.1 #! 符号含义

sha-bang

并非注释的意思,写在脚本开头.

用于指定脚本默认的命令解释器.

命令解释器 写法
bash #!/bin/bash
python #!/usr/bin/python2 或 #!/usr/bin/env python2

 

3.2 概述

执行方法

应用场景与说明

通过sh或bash🌟🌟🌟🌟🌟

书写脚本后,最常用的方式, 🌟

⚠ 在其他非红帽系统中,建议使用bash 运行脚本 .

通过.(点)或source 🌟

🅰 加载/生效配置文件(环境变量,别名) /etc/profile

🅱 常用:可以用来实现include功能,把其他脚本引入到当天脚本中

通过相对或绝对路径

我们一般不推荐使用这种,一般都是系统脚本/服调用的脚本,脚本需要加上执行权限才能用

输入重定向符号

不推荐使用.

 在Linux中,.(点命令)、bash和source的区别

# 在Linux中,.(点命令)、bash和source命令在执行脚本时有着明显的区别,主要体现在执行环境、脚本权限要求以及对当前shell环境的影响上。

1. 执行环境
.(点命令)和source命令:它们都是在当前shell环境下执行脚本,这意味着脚本中定义的变量、函数等环境变化会直接反映在当前shell会话中。
  由于不需要新启动一个子shell,这些命令执行效率也相对较高。实际上,.命令是source命令的另一种表示方式,两者在功能上是等价的。
bash命令:当使用bash script.sh这种方式执行脚本时,会启动一个新的bash子shell来执行脚本中的命令。这个子shell是独立的,
   它继承了父shell的环境变量和其他shell特性,但子shell中的变量和函数变化不会影响到父shell。
2. 脚本权限要求
.(点命令)和source命令:执行脚本时,不需要脚本文件具有执行权限。这是因为它们是在当前shell环境下读取并执行脚本内容,而不是直接执行脚本文件。
bash命令:当直接使用bash script.sh时,如果脚本文件没有执行权限,通常会因为权限不足而报错。但在某些情况下,如果bash能够直接读取脚本文件
  的内容(比如通过管道或重定向),则即使脚本没有执行权限也能被执行。然而,直接通过文件名调用bash执行脚本时,脚本文件通常需要具有执行权限。
3. 对当前shell环境的影响
.(点命令)和source命令:由于它们在当前shell环境下执行脚本,因此脚本中定义的变量、函数等环境变化会直接影响到当前shell会话。
  这对于需要重新加载配置文件(如.bashrc、.bash_profile等)或临时改变shell环境变量的场景非常有用。
bash命令:由于在新的子shell中执行脚本,脚本中的环境变化不会影响到父shell。这意味着脚本执行完毕后,父shell的环境变量、函数等状态将保持不变。
# 总结
.(点命令)和source命令适用于需要在当前shell环境下执行脚本并修改当前shell环境的场景。
bash命令适用于需要在独立的子shell中执行脚本的场景,或者当脚本文件需要执行权限时。

3.2.1 shbash

# Kylin-V10-sp3   sh是bash的软链接
[root@Kylin-V10-sp3 /server/scripts/shell-pro]# ll /bin/ | egrep -w ^'sh|bash'
-rwxr-xr-x 1 root root     1162856  8月 26  2022 bash
lrwxrwxrwx 1 root root           4  8月 26  2022 sh -> bash
[root@Kylin-V10-sp3 /server/scripts/shell-pro]# 

# centos7  sh是bash的软链接
[root@centos7 ~]# ll /bin/ | egrep -w ^'sh|bash'
-rwxr-xr-x. 1 root root    964536 Apr  1  2020 bash
lrwxrwxrwx. 1 root root         4 Aug 17 13:48 sh -> bash
[root@centos7 ~]#

# ubuntu2204 sh是dash的软连接
[root@ubuntu2204 /bin]# ll /bin/ | egrep -w '(bash|sh)'
-rwxr-xr-x  1 root root     1396520 Mar 14  2024 bash*
-rwxr-xr-x  1 root root        5188 Mar 25  2022 gettext.sh*
lrwxrwxrwx  1 root root           4 Mar 14  2024 rbash -> bash*
-rwxr-xr-x  1 root root       38964 Mar 22  2023 rescan-scsi-bus.sh*
lrwxrwxrwx  1 root root           4 Mar 23  2022 sh -> dash*
lrwxrwxrwx  1 root root           7 Aug 13 21:39 static-sh -> busybox*
[root@ubuntu2204 /bin]# 

# 综上所述shell脚本里 /bin/bash 通用

3.2.2 .source

[root@Kylin-V10-sp3 /server/scripts/shell-pro]# cat test.sh 
#!/bin/bash
##############################################################
# File Name:test.sh
# Version:V1.0
# Author:xk
# Organization: none
# Desc:
##############################################################

echo $a
[root@Kylin-V10-sp3 /server/scripts/shell-pro]# 
[root@Kylin-V10-sp3 /server/scripts/shell-pro]# a=123
[root@Kylin-V10-sp3 /server/scripts/shell-pro]# 
[root@Kylin-V10-sp3 /server/scripts/shell-pro]# bash test.sh 

[root@Kylin-V10-sp3 /server/scripts/shell-pro]# sh test.sh 

[root@Kylin-V10-sp3 /server/scripts/shell-pro]# . test.sh 
123
[root@Kylin-V10-sp3 /server/scripts/shell-pro]# source test.sh 
123
[root@Kylin-V10-sp3 /server/scripts/shell-pro]# 

# 原因参考上面  在Linux中,.(点命令)、bash和source的区别

3.2.3 相对或绝对路径

# 脚本中推荐使用绝对路径

3.2.4 使用重定向符号执行脚本

[root@Kylin-V10-sp3 /server/scripts/shell-pro]# cat test.sh 
#!/bin/bash
##############################################################
# File Name:test.sh
# Version:V1.0
# Author:xk
# Organization: none
# Desc:
##############################################################

echo $a
echo 123
[root@Kylin-V10-sp3 /server/scripts/shell-pro]# 
[root@Kylin-V10-sp3 /server/scripts/shell-pro]# sh < test.sh 

123
[root@Kylin-V10-sp3 /server/scripts/shell-pro]# 

4. 变量

4.1 变量

变量variable 变化。

小学题:已知 x=30,x+y=20 ,问y=?,y叫未知数.

查看变量内容$变量名字

赋值a = 123

变量的本质:内存中的一块空间,变量名字==>内存空间地址.

[root@Kylin-V10-sp3 /server/scripts/shell-pro]# a=123
[root@Kylin-V10-sp3 /server/scripts/shell-pro]# echo $a
123
[root@Kylin-V10-sp3 /server/scripts/shell-pro]

4.2 变量命名

变量名字命名要求:

  1. 不能以数字开头。
  2. 不能以特殊符号开头,可以以"_"开头。
  3. 推荐字母开头

变量的命名方式:

  1. 驼峰方式: personOfName personOfAge
  2. 现代式: 单词(小写)+ "_下划线"连接 person_of_name
  3. 不要写不能直接表示含义的变量. 

4.3 变量分类

分类

说明

要求

普通变量 (局部变量)

我们在脚本中通过 a=形式创建就是普通变量

常用,必会

环境变量(全局变量)

一般都是系统创建,PATH,PS1,LANG...

掌握几个常用的环境变量及含义

特殊变量⭐ ⭐ ⭐

$+特殊符号, shell脚本,命令,各种方面.

shell编程核心

 

4.3.1 普通变量

$与${}一致,可以用于取值。
$变量
${变量} 指定变量名字

day=6
echo $day
6
echo ${day}hao
6hao

4.3.2 环境变量

全局变量: 1处定义,处处使用.

大部分都是系统定义的,我们一般就是修改.

[root@Kylin-V10-sp3 ~]# export
declare -x DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/0/bus"
declare -x HISTCONTROL="ignoredups"
declare -x HISTSIZE="1000"
declare -x HOME="/root"
declare -x HOSTNAME="Kylin-V10-sp3"
declare -x LANG="zh_CN.UTF-8"
declare -x LOGNAME="root"
declare -x LS_COLORS="rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.webp=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:"
declare -x MAIL="/var/spool/mail/root"
declare -x MOTD_SHOWN="pam"
declare -x OLDPWD
declare -x PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/root/bin"
declare -x PS1="[\\[\\e[34;1m\\]\\u@\\[\\e[0m\\]\\[\\e[32;1m\\]\\H\\[\\e[0m\\]\\[\\e[31;1m\\] \\w\\[\\e[0m\\]]\\\$ "
declare -x PWD="/root"
declare -x SHELL="/bin/bash"
declare -x SHLVL="1"
declare -x SSH_CLIENT="10.0.0.1 61241 22"
declare -x SSH_CONNECTION="10.0.0.1 61241 10.0.0.36 22"
declare -x SSH_TTY="/dev/pts/0"
declare -x TERM="xterm"
declare -x USER="root"
declare -x XDG_RUNTIME_DIR="/run/user/0"
declare -x XDG_SESSION_CLASS="user"
declare -x XDG_SESSION_ID="6"
declare -x XDG_SESSION_TYPE="tty"
[root@Kylin-V10-sp3 ~]# 
[root@Kylin-V10-sp3 ~]# 
[root@Kylin-V10-sp3 ~]# env
SHELL=/bin/bash
HISTCONTROL=ignoredups
HISTSIZE=1000
HOSTNAME=Kylin-V10-sp3
PWD=/root
LOGNAME=root
XDG_SESSION_TYPE=tty
MOTD_SHOWN=pam
HOME=/root
LANG=zh_CN.UTF-8
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.webp=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:
SSH_CONNECTION=10.0.0.1 61241 10.0.0.36 22
XDG_SESSION_CLASS=user
TERM=xterm
USER=root
SHLVL=1
XDG_SESSION_ID=6
XDG_RUNTIME_DIR=/run/user/0
PS1=[\[\e[34;1m\]\u@\[\e[0m\]\[\e[32;1m\]\H\[\e[0m\]\[\e[31;1m\] \w\[\e[0m\]]\$ 
SSH_CLIENT=10.0.0.1 61241 22
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/root/bin
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/0/bus
MAIL=/var/spool/mail/root
SSH_TTY=/dev/pts/0
_=/usr/bin/env
[root@Kylin-V10-sp3 ~]# 

 

环境变量名字

含义

应用场景

PATH

⭐ ⭐ ⭐ ⭐ ⭐

记录命令位置的环境变量,运行命令的时候bash会在PATH的路径中查找

通过二进制包或编译安装软件,增加新的命令路径

LANG

⭐ ⭐ ⭐ ⭐ ⭐

系统语言与字符集Language 

LANG=zh_CN.UTF8 中文

LANG=en_US.UTF8  英文

修改语言字符集

export LANG=en_US.UTF8(常用)

PS1

⭐ ⭐   

修改命令行格式,生产环境不推荐修改.

UID或EUID

⭐ ⭐

用户的uid,用于判断当前用户是否为root

用于脚本判断用户是否root.

HOSTNAME

⭐ ⭐

主机名

 

历史四人组

 

history命令 历史命令相关

 

HISTSIZE

⭐ ⭐

history 命令记录最多多条指令, 生产环境尽量少

未来安全优化配置

HISTFILESIZE

⭐ ⭐

history 历史记录文件的大小 ~/.bash_history 生产环境尽量少

未来安全优化配置

HISTCONTROL

⭐ ⭐

控制历史命令记录或不记录哪些内容 生产环境ignorespace 以空格开头的命令不记录

 

未来安全优化配置

HISTFILE

⭐ ⭐

 

指定历史命令的记录文件的名字和位置.

默认当前用户家目录 .bash_history

 

未来安全优化配置 或 手写跳板机/行为审计

PROMPT_COMMAND

⭐ ⭐

存放命令,命令行执行命令后会运行这个变量的内容,用于实现行为审计(记录用户操作)

手写跳板机/行为审计

IFS

⭐ ⭐

类似于awk -F 指定分隔符(指定每一列的分隔符)

一般与循环配合读取文件内容

TMOUT

⭐ ⭐

超时自动退出时间

未来安全优化配置

修改环境变量

export 创建或修改全局变量(环境变量)
# 案例01 把当前系统语言改为中文,字符集改为UTF-8
export LANG=zh_CN.UTF-8

#永久的就是写入到 /etc/profile最后即可.
source /etc/profile
env |grep LANG
LANG=zh_CN.UTF-8

4.3.3 环境变量相关文件及目录

修改rm别名的时候为何修改/etc/profile后不生效?还需要修改~/.bashrc

文件或目录

 

应用场景

/etc/profile

全局生效(国法) 存放函数,环境变量。存放别名

未来主要使用这个即可.

/etc/bashrc

全局生效(国法) 存放别名。

 

~/.bashrc

家规(局部生效)

 

~/.bash_profile

家规(局部生效)

 

/etc/profile.d/

目录,每个用户登录的时候(远程连接与su切换),加载目录下面.sh结尾的文件.

简单设置一些登录登录后提示,变化.

 

4.3.4 特殊变量 ⭐⭐⭐⭐⭐

linux,shell编程中有各种各样的特殊变量,方便对参数,命令结果,进行判断与对比

特殊变量分类

核心

位置相关的特殊变量

⭐⭐⭐⭐⭐

状态相关的特殊变量

⭐⭐⭐⭐⭐

变量子串

⭐、

变量扩展

4.3.4.1 特殊变量-位置变量

位置的特殊变量

含义

应用场景

$n(数字)

脚本的第n个参数

命令行与脚本内部桥梁.

$0

脚本的名字

用于输出脚本的格式或帮助的时候。用于错误提示输出帮助。

$#

脚本参数的个数

一般与判断结合,检查脚本参数个数。

$@

取出脚本所有参数(2, 4....$n)。

数组中或循环中。

$*

取出脚本所有参数(2, 4....$n)。

数组中或循环中。

4.3.4.1.1 $n 位置参数

4.3.4.1.2 练习

1.书写脚本每次用户登录后显示系统的基本信息。 ⭐⭐⭐⭐⭐

查看代码
 # 1.书写脚本 (推荐存放位置 /server/scripts/shell-pro/)

#!/bin/bash
##############################################################
# File Name:sys_cfg.sh
# Version:V1.0
# Author:xk
# Organization: none
# Desc:
##############################################################


#########
#1.赋值##
#########
sys_hostname=`hostname`
sys_ip_addrs=`hostname -I`
sys_mem_total=`free -h |awk 'NR==2{print  $2}'`
sys_mem_free=`free -h |awk 'NR==2{print  $NF}'`
sys_load=`uptime |awk '{print  $(NF-2),$(NF-1),$NF}'`

#########
#2.输出##
#########
cat <<EOF
      主机名:   ${sys_hostname}
      ip地址:   ${sys_ip_addrs}
      总内存:   ${sys_mem_total}
      可用内存: ${sys_mem_free}
      系统负载: ${sys_load}
EOF


# 2.创建软链接
[root@Kylin-V10-sp3 /etc/profile.d]# ls
bash_completion.sh  colorls.csh  colorls.sh  csh.local  gawk.csh  gawk.sh  lang.csh  lang.sh  sh.local  system-info.sh
[root@Kylin-V10-sp3 /etc/profile.d]# 
[root@Kylin-V10-sp3 /etc/profile.d]# ln -s /server/scripts/shell-pro/sys_cfg.sh /etc/profile.d/sys_cfg.sh
[root@Kylin-V10-sp3 /etc/profile.d]# 
[root@Kylin-V10-sp3 /etc/profile.d]# ll
总用量 40
-rw-r--r-- 1 root root  729  3月  6  2021 bash_completion.sh
-rw-r--r-- 1 root root 1741  4月 20  2022 colorls.csh
-rw-r--r-- 1 root root 1606  4月 20  2022 colorls.sh
-rw-r--r-- 1 root root   80  3月 13  2021 csh.local
-rw-r--r-- 1 root root 1107  1月 25  2019 gawk.csh
-rw-r--r-- 1 root root  757  1月 25  2019 gawk.sh
-rw-r--r-- 1 root root 3562  3月 13  2021 lang.csh
-rw-r--r-- 1 root root 3187  3月 13  2021 lang.sh
-rw-r--r-- 1 root root   81  3月 13  2021 sh.local
lrwxrwxrwx 1 root root   36  9月 19 17:44 sys_cfg.sh -> /server/scripts/shell-pro/sys_cfg.sh
-rw-r--r-- 1 root root 1873  3月 24  2023 system-info.sh
[root@Kylin-V10-sp3 /etc/profile.d]# 


# 3 断开当前会话窗口,重新链接。
/**
 * _ooOoo_
 * o8888888o
 * 88" . "88
 * (| -_- |)
 *  O\ = /O
 * ___/`---'\____
 * .   ' \\| |// `.
 * / \\||| : |||// \
 * / _||||| -:- |||||- \
 * | | \\\ - /// | |
 * | \_| ''\---/'' | |
 * \ .-\__ `-` ___/-. /
 * ___`. .' /--.--\ `. . __
 * ."" '< `.___\_<|>_/___.' >'"".
 * | | : `- \`.;`\ _ /`;.`/ - ` : | |
 * \ \ `-. \_ __\ /__ _/ .-` / /
 * ======`-.____`-.___\_____/___.-`____.-'======
 * `=---='
 *          .............................................
 *           佛曰:bug泛滥,我已瘫痪!
 */




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


Activate the web console with: systemctl enable --now cockpit.socket

Last login: Thu Sep 19 17:39:44 2024 from 10.0.0.1

# 看到如下内容即设置成功
      主机名:   Kylin-V10-sp3
      ip地址:   10.0.0.36 
      总内存:   948Mi
      可用内存: 528Mi
      系统负载: 0.00, 0.00, 0.00
[root@Kylin-V10-sp3 ~]# 

2.执行脚本的时候输入用户名,判断用户名是否存在

查看代码
 #!/bin/bash
##############################################################
# File Name:check_user.sh
# Version:V1.0
# Author:xk
# Organization: none
# Desc:
##############################################################

# 1 定义变量
user=$1

# 2 检查脚本参数个数
if [ $# -ne 1 ];then
    echo '脚本使用格式: ' $0 '用户名'
    exit 0
fi

id $user > /dev/null 2>&1 


# 3 检查用户是否存在
if [ $? -eq 0 ];then
    echo '用户' $user '存在'
else
    echo '用户' $user '不存在'
fi

# 调用脚本
[root@Kylin-V10-sp3 /server/scripts/shell-pro]# bash check_user.sh
脚本使用格式:  check_user.sh 用户名
[root@Kylin-V10-sp3 /server/scripts/shell-pro]# bash check_user.sh xk
用户 xk 不存在
[root@Kylin-V10-sp3 /server/scripts/shell-pro]# bash check_user.sh root
用户 root 存在
[root@Kylin-V10-sp3 /server/scripts/shell-pro]#


# 判断多用户是否存在

# 传进来的所有用户
users="$@"

# 传参为空,提示正确格式
if [ $# -eq 0 ];then
    echo "使用格式:" $0 " user1 user2 ..."
    exit 
fi

# 循环用户
for user in $users;
do
    id $user >/dev/null 2>&1
    # id 用户名  结果为0,用户存在
    if [ $? -eq 0 ];then
        echo $user ": 存在"
    else
	echo $user ": 不存在"
    fi
	    
done

# exit退出脚本,结束执行退出脚本.
# exit 数字,脚本的返回值

3. 检查ip或域名是否可以访问脚本

# 1.脚本内容

#!/bin/bash
##############################################################
# File Name:check_ip.sh
# Version:V1.0
# Author:xk
# Organization: none
# Desc:
##############################################################

ip=$1

if [ $# -ne 1 ];then
    echo 'ip or DNS 不存在'
    exit
fi

ping -nc1 $ip >/dev/null 2>&1

if [ $? -eq 0 ];then
    echo $ip "可以访问脚本"
else
    echo $ip "不能访问脚本"
fi


# 2.调用
[root@Kylin-V10-sp3 /server/scripts/shell-pro]# bash check_ip.sh 10.0.0.37
10.0.0.37 可以访问脚本
[root@Kylin-V10-sp3 /server/scripts/shell-pro]# bash check_ip.sh
ip or DNS 不存在

4.面试题: $n n大于9 会有什么问题?

[root@Kylin-V10-sp3 /server/scripts/shell-pro]# cat test.sh 
#!/bin/bash
##############################################################
# File Name:test.sh
# Version:V1.0
# Author:xk
# Organization: none
# Desc:
##############################################################

# echo $a
echo 脚本传参:$1 ,$2 ,$3 ,$10 , $11 ,$12
echo 脚本传参2:$1 ,$2 ,$3 ,${10} , ${11}, ${12}
echo 脚本名字:$0
echo 传参个数:$#
[root@Kylin-V10-sp3 /server/scripts/shell-pro]#
[root@Kylin-V10-sp3 /server/scripts/shell-pro]# bash test.sh nice beautiful {a..z}
脚本传参:nice ,beautiful ,a ,nice0 , nice1 ,nice2
脚本传参2:nice ,beautiful ,a ,h , i, j
脚本名字:test.sh
传参个数:28
[root@Kylin-V10-sp3 /server/scripts/shell-pro]#

# 脚本传参:nice ,beautiful ,01 ,nice0 , nice1 ,nice2   # nice0 , nice1 ,nice2 异常
# 脚本传参2:nice ,beautiful ,a ,h , i, j               # 使用${}的正常了.   

5.执行脚本输入1个或多个用户名,通过脚本进行输.()

[root@Kylin-V10-sp3 /server/scripts/shell-pro]# cat check_multi_users.sh
#!/bin/bash
##############################################################
# File Name:check_multi_users.sh
# Version:V1.0
# Author:xk
# Organization: none
# Desc:
##############################################################

# 传进来的所有用户
users="$@"

# 传参为空,提示正确格式
if [ $# -eq 0 ];then
    echo "使用格式:" $0 " user1 user2 ..."
    exit 
fi

# 循环用户
for user in $users;
do
    id $user >/dev/null 2>&1
    # id 用户名  结果为0,用户存在
    if [ $? -eq 0 ];then
        echo $user ": 存在"
    else
	echo $user ": 不存在"
    fi
	    
done

# 调用
[root@Kylin-V10-sp3 /server/scripts/shell-pro]# 
[root@Kylin-V10-sp3 /server/scripts/shell-pro]# bash check_multi_users.sh 
使用格式: check_multi_users.sh  user1 user2 ...
[root@Kylin-V10-sp3 /server/scripts/shell-pro]# 
[root@Kylin-V10-sp3 /server/scripts/shell-pro]# bash check_multi_users.sh xk root
xk : 存在
root : 存在
[root@Kylin-V10-sp3 /server/scripts/shell-pro]# bash check_multi_users.sh xk xk2
xk : 存在
xk2 : 不存在
[root@Kylin-V10-sp3 /server/scripts/shell-pro]# 

6.书写一个回收站脚本,替代rm命令.

 思路

# 脚本详细流程:

1.检查脚本参数个数等于0则报错并退出.
2.脚本创建回收站目录mktemp命令创建临时目录
3.把删除的文件或目录移动到这个临时目录中.
4 输出表示已经移动到回收站(临时目录名字)
5. 执行脚本传入参数被删除的文件或目录. bash recycle.sh /root/test 

mktemp -dp /recycle/ 在指定目录下面创建随机目录
默认创建随机文件,在/tmp/
-d创建随机目录
-p指定在哪个目录下面创建随机内容


# 后期需求:

追加需求:禁止删除/etc/ /根目录 /tmp/ /usr /var/
较为复杂的需求:书写恢复的功能.(删除的时候记录文件,记录目录路径.)
rm命令如果加上选项-fr -f 

书写回收站脚本.
查看代码
 # 1.书写脚本 

#!/bin/bash
##############################################################
# File Name:recycle.sh
# Version:V1.0
# Author:xk
# Organization: none
# Desc:
##############################################################

# 移动内容
files="$*"
# 移动目录
path="/recycle/"

if [ $# -eq 0 ];then
    echo "help:删除内容不存在" 
    exit
fi

# mkdir -p $path
# 随机创建子目录
tmp_path=`mktemp -d -p $path`

# 移动文件
mv -t ${tmp_path} ${files}

if [ $? -eq 0 ];then
    echo "移动成功,移动到:" ${tmp_path}
else
    echo "移动失败"
fi

# 2.设置别名
[root@Kylin-V10-sp3 /server/scripts/shell-pro]# alias rm='bash /server/scripts/shell-pro/recycle'
[root@Kylin-V10-sp3 /server/scripts/shell-pro]# 
[root@Kylin-V10-sp3 /server/scripts/shell-pro]# vim /etc/profile
[root@Kylin-V10-sp3 /server/scripts/shell-pro]# 
[root@Kylin-V10-sp3 /server/scripts/shell-pro]# source /etc/profile
[root@Kylin-V10-sp3 /server/scripts/shell-pro]# tail -n1 /etc/profile
alias rm='bash /server/scripts/shell-pro/recycle.sh'
[root@Kylin-V10-sp3 /server/scripts/shell-pro]#
[root@Kylin-V10-sp3 /server/scripts/shell-pro]# cat /root/.bashrc 
# .bashrc

# User specific aliases and functions

#alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'

# Source global definitions
if [ -f /etc/bashrc ]; then
	. /etc/bashrc
fi
[root@Kylin-V10-sp3 /server/scripts/shell-pro]# 

# 3.调用脚本
[root@Kylin-V10-sp3 ~]# cd test/
[root@Kylin-V10-sp3 ~/test]# 
[root@Kylin-V10-sp3 ~/test]# rm 01.txt 
移动成功,移动到: /recycle/tmp.XEXKWS1lzV
[root@Kylin-V10-sp3 ~/test]# 
[root@Kylin-V10-sp3 ~/test]# ls /recycle/tmp.XEXKWS1lzV/
01.txt
[root@Kylin-V10-sp3 ~/test]# 
4.3.4.1.3 了解: $* $@

参数个数不确定

$@和$*区别: 仅仅在加上双引号后才有

共同点

区别

$@

取出脚本所有的参数

加上双引号 会识别 合并在一起的参数,独立参数,正常的理解.

$*

取出脚本所有的参数

加上双引号 所有参数合并为1个参数

 

[root@Kylin-V10-sp3 ~/test]# set "I am boy" handsome man
[root@Kylin-V10-sp3 ~/test]# 
[root@Kylin-V10-sp3 ~/test]# for i in "$*";  do echo $i; done
I am boy handsome man
[root@Kylin-V10-sp3 ~/test]# 
[root@Kylin-V10-sp3 ~/test]# for i in "$@";  do echo $i; done
I am boy
handsome
man
[root@Kylin-V10-sp3 ~/test]# 
4.3.4.1.4 特殊变量之位置变量小结

位置的特殊变量

重要

含义

应用场景

$n(数字) 命令行传参

⭐⭐⭐⭐⭐

脚本的第n个参数

使用最多,命令行与脚本内部桥梁. (命令行传参)

$0

⭐⭐⭐⭐

脚本的名字

用于输出脚本的格式或帮助的时候。用于错误提示输出帮助。

$#

脚本参数的个数

一般与判断结合,检查脚本参数个数。

$@

取出脚本所有参数。

数组中或循环中。

$*

取出脚本所有参数。

数组中或循环中。

 

posted @ 2024-09-19 21:48  老虎死了还有狼  阅读(8)  评论(0编辑  收藏  举报