在UNIX和类UNIX操作系统中,Shell是一个非常重要的组件,为用户提供了操作系统的各种功能和命令,如文件管理、进程管理、网络管理等等。与其他编程语言不同,Shell语言具有解释性,其脚本作为文本文件存储,可以直接运行,也可以用来编写脚本程序。
Shell是一种命令行解释器,可以理解为一种软件程序,它接收用户输入的命令并将其转换为操作系统内核能够理解的指令,然后将结果返回给用户。 Shell通常运行在操作系统的用户空间中,作为操作系统和用户之间的接口。
常见的Shell包括Bash、Korn Shell、C Shell等,其中Bash在大多数Linux发行版中被广泛使用。由于Shell的灵活性和易用性,它被广泛用于自动化脚本编写、系统管理、软件配置等领域。

- #查看 shell 命令解释器的路径
- [root@localhost ~]# cat /etc/shells
- #查看 默认的命令解释器
- [root@localhost ~]# echo $SHELL # $ 用于提取变量值
- #创建脚本文件
- [root@localhost ~]# vim test1.sh #.sh扩展名不能更改
- #编辑文件 ~/.vimrc 自动化生成脚本抬头信息
- #写入以下内容
- #第一行为文件检索的识别功能:给以.py .cc .sh .java 结尾的文件自动添加抬头信息
- autocmd BufNewFile *.py,*.cc,*.sh,*.java exec ":call SetTitle()"
-
- func SetTitle() #添加一个名为SetTitle的函数
- if expand("%:e") == 'sh' #如果调用的文件扩展名是.sh
- call setline(1,"#!/bin/bash") #增加脚本解释器
- call setline(2,"#########################")
- call setline(3,"#File name:".expand("%"))
- call setline(4,"#Version:v1.0")
- call setline(5,"#Email:admin@test.com")
- call setline(6,"#Created time:".strftime("%F %T"))
- call setline(7,"#Description:")
- call setline(8,"#########################")
- call setline(9,"")
- endif
- endfunc
脚本中尽量不用中文注释
多使用内部命令
没有必要使用cat命令
- [root@server ~]# cat /etc/passwd | grep root
-
- [root@server ~]# grep root /etc/passwd
仔细阅读出错信息
文件名以sh结尾
代码缩进:
- for ((i=1;i<10;i++))
- do
- echo -ne "$i\t" # /t 会被解释为一个制表符,用于在文本中对齐或缩进内容。
- done # -ne 代表取echo 默认换行
-
- echo #后面没有内容的 echo 代表换行
-
- for ((i=1;i<70;i++))
- do
- echo -n "@"
- done
-
- echo
-
- for ((i=1;i<10;i++))
- do
- for ((j=1;j<=i;j++))
- do
- echo -en "$i*$j=$[i*j]\t"
- done
- echo
- done
- [root@timeserver ~]# bash test2.sh
- [root@timeserver ~]# /root/test2.sh #需要增加文件权限 X
- #bash 时无需增加权限,bash命令自带执行权限,会将/root/test2.sh当作参数执行
- [root@timeserver ~]# bash /root/test2.sh
-n :取消输出后行末的换行符号
-e :启用转义字符
格式:echo -e "\e[字体控制;字体颜色或背景色 字符串内容 \e[0m"
\e[表示控制开始,\e[0m表示控制结束
字体控制选项:1表示高亮,4表示下划线,5颜色闪烁
颜色如下:字颜色:30-37 , 背景色:40-47
- [root@server ~]# vim color.sh
- echo -e "\e[30m 黑色字\e[0m"
- echo -e "\e[1;31m 紅色字\e[0m"
- echo -e "\e[32m 綠色字\e[0m"
- echo -e "\e[33m 黃色字\e[0m"
- echo -e "\e[34m 藍色字\e[0m"
- echo -e "\e[35m 紫色字\e[0m"
- echo -e "\e[36m 天藍字\e[0m"
- echo -e "\e[37m 白色字\e[0m"
- echo -e "\e[40;37m 黑底白字\e[0m"
- echo -e "\e[41;37m 紅底白字\e[0m"
- echo -e "\e[42;37m 綠底白字\e[0m"
- echo -e "\e[43;37m 黃底白字\e[0m"
- echo -e "\e[44;37m 藍底白字\e[0m"
- echo -e "\e[45;37m 紫底白字\e[0m"
- echo -e "\e[46;37m 天藍底白字\e[0m"
- echo -e "\e[47;30m 白底黑字\e[0m"
- [root@server ~]# bash color.sh
默认 printf 不会像 echo 自动添加换行符,我们可以手动添加 /n
格式:printf 格式控制字符串 参数列表
- [root@server ~]# echo "Hello, Shell"
- [root@server ~]# printf "Hello, Shell\n"
- [root@server ~]# printf "%d %s\n" 1 "abc"
- [root@server ~]# printf '%d %s\n' 1 "abc" # 单引号双引号效果一样
- [root@server ~]# printf %s abcdef # 没有双引号也可输出,没有\n会续连下一个提示符
- [root@server ~]# printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg
- # %s %c %d %f 都是格式替代符,%s 输出一个字符串,%d 整型输出,%c 输出一个字符,%f 输出实
- 数,以小数形式输出。
- # %-10s 指一个宽度为 10 个字符(- 表示左对齐,没有则表示右对齐),任何字符都会被显示在 10 个字符
- 宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。
- [root@server ~]# printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234
- # %-4.2f 指格式化为小数,其中 .2 指保留2位小数
history命令用于显示当前用户执行过的命令列表。当在Shell中执行命令时,Shell会将命令记录在历史列表中,以便后续使用。
格式:history [参数] [历史命令保存文件]
参数:-c :清空历史命令记录
-w:把缓存中的历史命令写入历史命令保存文件。如果不手工指定历史命令保存文件,则放 入默认 历史命令保存文件~/.bash_history 中
修改默认记录历史命令条数:
- [root@server ~]# vim /etc/profile
- #找到如下内容,一般在49行 修改历史列表中命令记录的上限数
- HISTSIZE=1000
alias 命令允许你为经常使用的命令设置简短的别名。这样你就可以使用更短的命令来调用常用的命令,提高工作效率。
格式:alias 别名=原命令
- [root@server ~]# alias ll='ls -l'
- #这样,每次你输入 ll 命令时,实际上会被替换为 ls -l 命令。
- #为了让这个别名在当前账户下永久生效,可以把别名写入环境变量配置文件“~/.bashrc”。
- [root@server ~]# cat ~/.bashrc # 在最下面增加、
-
- ##为了让别名不受限于账户永久生效,可以把别名写入/etc/bashrc
- #使用以下命令使配置永久生效
- [root@server ~]# source /etc/bashrc
- [root@server ~]# date ; ls -l /etc/passwd
- 2023年 10月 23日 星期一 16:40:23 CST
- -rw-r--r--. 1 root root 2181 10月 7 15:03 /etc/passwd
- [root@timeserver ~]# [root@server ~]# mkdir /mnt/iso && mount /dev/sr0 /mnt/iso
- bash: [root@server: command not found...
- [root@timeserver ~]# [root@server ~]# mkdir tt || ls /
- bash: [root@server: command not found...
- afs bin boot dev etc home lib lib64 media mnt opt proc root run sbin shell srv sys tmp usr var www
案列1:
- # 若账户fox10不存在,则添加账户
- [root@server ~]# id fox10 &> /dev/null &&
- echo "fox10已存在" || useradd fox10
- # &> /dev/null 表示将左侧命令执行的正确和错误输出
- 到“黑洞”即不显示到屏幕
案列 2:判断当前已登录账户数,若超过5个则输出“Too many”
- [root@server ~]# num=$(who | cut -d " " -f1
- | sort -u | wc -l)
- [root@server ~]# [ $num -gt 5 ] && echo "Too many" || echo "已登录账户数:$num"
- 已登录账户数:1
- # who : 查看当前已登录的账户信息
- # cut -d " " -f1 :以空格为列向分割符,截取第1部分
- # sort -u :去重后排序
案列 3: 编写脚本temp2.sh ,程序从键盘读入一个目录名, 判断该命令是否存在,若不存在则创建,并显示目录信息
- [root@server ~]# vim temp2.sh
- #!/bin/bash
- cd /
- ls
- read -p "请输入一个目录名:" dir
- test -d $dir && ls -l $dir || (echo "目录不存在,开始新建..." ; mkdir $dir ; ls -l $dir)
案列 4: 编写temp5.sh脚本显示所有用户,选择一个用户输 入,判断是root账户还是系统账户还是普通账户
- [root@server ~]# vim temp5.sh
- #!/bin/bash
- cat /etc/passwd | cut -d ":" -f1 | sort -u
- read -p "请输入一个账户名:" us
- us_num=$(id -u $us)
- if (($us_num==0))
- then
- echo "此用户为管理员账户"
- else
- if (($us_num>=1 && $us_num<=999))
- then
- echo "此账户为系统账户"
- else
- echo "普通账户"
- fi
- fi
管道符
|是 Linux/Unix 系统中使用的一个特殊符号,用于连接两个命令并将前一个命令的输出作为后一个命令的输入。
- [root@timeserver ~]# echo 1 > tt | cat tt
- 1
例:检索本机IP地址和子网掩码
- #截取 IP 地址
- [root@timeserver ~]# ip a | grep ens160 | grep inet | tr -s " " | cut -d " " -f3
- 192.168.186.100/24
- 192.168.186.200/24
- #截取子网掩码
- [root@timeserver ~]# ip a | grep ens160 | grep inet | tr -s " " | cut -d " " -f3 | cut -d "/" -f2
- 24
- 24
- #tr -s " " :将多个空格替换为一个空格
- #cut -d " " -f3 :-d 指定列之间的分隔符 #以空格为分隔符号截取第三列
- 0----------------命令运行成功
- 1----------------通知未知错误
- 2----------------误用shell命令
- 126-------------命令不可执行
- 127-------------没有找到命令
- 128-------------无效退出参数
- 128+x-----------linux信号x的严重错误
- 130--------------命令通过Ctrl+C终止
- 255--------------退出状态码越界
不同情况下,程序返回的状态码
- [root@server ~]# echo "china"
- china
- [root@server ~]# echo $?
- 0
- [root@server ~]# ehco "china"
- bash: ehco: command not found...
- Similar command is: 'echo'
- [root@server ~]# echo $?
- 127