解决方案

Shell脚本基本语法大全

seo靠我 2023-09-24 13:57:21

目录

1.如何理解Shell脚本

2.如何一行执行多条命令

3.脚本的执行

4.管道与重定向

5.变量的使用

6.数组的使用

7.转义和引用

8.运算符

9.各种特殊符号

10.测试与判断

11.分支语句

12.循环

12.函SEO靠我

13.脚本优先级

14.信号通信

15.计划任务

1.如何理解Shell脚本

Shell是命令解析器,用于解释用户对操作系统的操作。将用户的命令写入文件通过命令解释器进行操作就变成了Shell脚本。ShelSEO靠我l的种类有很多种,包括sh、csh、tcsh、ash、bash。CetOS7默认采用的是bash,可以通过/etc/shells查看操作系统使用的shell的类型

2.如何一行执行多条命令

一般建议一条命SEO靠我令只做一件事情,为了组合多条命令,我们一般使用脚本文件来保存需要执行的命令。并且赋予文件可执行权限,赋予权限的命令如下:

chmod u+rx shellfilename

在Shell脚本的开头我们需要指SEO靠我定采用哪种命令解释器(注意要以#开头)

#!/bin/bash

Shell文件中一般一行对应一条命令我们可以通过分号组合多条命令

cd /home/ ; ls ; pwd

3.脚本的执行

执行Shell脚本有两SEO靠我种方法,一种方法会创建子进程执行shell命令,另一种会在当前进程执行shell脚本,影响当前环境。

方法一(创建子进程执行shell脚本,不影响当前环境)bash ./filename.bash   SEO靠我#可以不用赋予可执行权限 ./filename.sh

方法二(不创建子进程执行,影响当前环境)

source ./filename.sh .  ./filename.sh

4SEO靠我.管道与重定向

管道和信号一样,是进程间通信的一种方式,匿名管道是Shell常用的通信方式之一用于将一个命令的执行结果传递给后面的命令。管道符号是"|"。

ps | cat #将ps的执行结果传递给catSEO靠我 echo hello | ps #将echo的结果传递给 ps

如果执行的命令是两个外部命令的话,管道会创建两个子进程然后通过管道连接两个子进程。如果子进程中有内建的命令不会传递给父进SEO靠我程。

一个进程默认会打开标准输入、标准输出、错误输出三个文件描述符。通过这三个文件描述符我们可以实现内容的输入和输出。

输入重定向符号"<" 

使用输入重定向符号可以将外部文件内容输入到变量read var SEO靠我< /path/testfile echo $var

输出重定向符号包括">"  ">>"  "2>" "&>"

> 会清空文件中的原有内容 echo 123 > /path/file

>> SEO靠我会向文件中追加对应的内容

2> 设置错误重定向,将错误信息输出到对应的文件

&> 输出所有内容到对应的文件(正常内容和错误内容) wc -l < /etc/passwd #统计文件中的行数

可以将输入和输出重SEO靠我定向符号组合到一起使用

cat > /root/fileconfig/test.sh << EOF echo "hello world" EOF

5.变量的使用

变量的定义

SEO靠我式: 变量名=变量值 等号两侧不能有空格 a=123

也可以使用let为变量赋值

let vara=10+20

也可以将命令赋值给变量

l=ls

将命令的执行结果赋值给变量,使用$()或者` `

letc=$(lsSEO靠我 -l /etc) letc=`ls -l /etc`

如果变量值中有空格等特殊字符可以包含在" "(双引号)或者 (单引号)中 

变量的引用

通过${变量名}来对变量的值进行引用

echo $SEO靠我{变量名} 查看变量的值

${变量名}在部分场景下可以省略为$变量名

变量的作用范围

默认变量的作用范围为当前终端,对父进程和子进程不生效。不过如果导出变量之后变量可以对子进程产生影响。子进程可以获得父进程SEO靠我的变量名称 export test_var

可以使用unset命令对变量取消赋值

unset test_var

系统环境变量

环境变量是每个Shell打开都可以获得的变量

set: 显示(设置)shell变量 包SEO靠我括的私有变量以及用户变量

不同类的shell有不同的私有变量 bash,ksh,csh每中shell私有变量都不一样。

env:显示(设置)用户变量

export:显示(设置)当前导出成用户变量的shellSEO靠我变量

除了上面的这些命令之外Shell中还有一些特殊的变量$?  #用来判断上一条命令是否正确执行 $$  显示当前进程的PID $0 获得当前进程的名称 SEO靠我 $PATH 当前的环境变量 $PS1  用来定义命令行提示符的环境变量

向环境变量中追加环境变量

PATH=$PATH:/root #追加环境变量

所有的环境变量都export过,对子终端SEO靠我生效对新终端不生效

export PATH=:$PATH:/root/

环境变量的配置文件

#系统和终端使用的环境变量 /etc/profile /etc/profile.dSEO靠我/ /etc/bashrc #用户使用的环境量 ~/.bash_profile ~/.bashrc

使用不同的方式切换用户,会获得不同的环SEO靠我境变量

su username (nologin shell) #会使用下面文件中的环境变量 .bashrc /etc/bashrcsu - usernaSEO靠我me(login shell) #会使用所有文件中的环境变量 /etc/profile .bash_profile .bashrc SEO靠我 /etc/bashrc

环境变量配置之后不会立即生效,可以通过下面的命令使其生效

source /etc/bashrc 使其生效

如果觉得命令太长可以给各个命令指定一个别名

alias rm = SEO靠我rm -i

位置变量

$1 $2....用来表示传入脚本或者函数的位置参数

$0 在脚本中执行用来表示脚本的路径

在读取环位置变量的时候如果位置变量不存在则为空,如果不想显示为空可以给变量指定一个默认的值,在SEO靠我变量不存在的时候使用默认的值。 ${2-999}  #第二个参数如果不存在的时候则用999替换对应的变量值

6.数组的使用

定义数组的时候通过小括号指定数组类型,数组元素之间通过空格划分

ARRAY=( 10SEO靠我.0.0.1  10.0.0.2  10.0.0.3 )

显示数组的所有元素

echo  ${ARRAY[@]}

显示数组元素的个数

echo ${#ARRAY[@]}

显示数组的第n元素  编号是从0开始的

eSEO靠我cho ${ARRAY[n]}

7.转义和引用

需要注意的Shell脚本中的一些特殊符号

# 用来进行注释 ; 用来连接两个命令或者脚本 \ 用来对一些符号进行转义 " 和 用来引用一些字符串

通过\来对一SEO靠我些符号进行转义

\n \r \t 对单个字母进行转义 \$ \" \\ 对单个非字母进行转义

常用的引用符号

"  双引号 单引号 ` 反引号 $var  变量不会解释 "$var"  变量会解释

8.运算SEO靠我

赋值运算

=赋值运算符,用于算术赋值和字符串赋值

使用unset 取消变量赋值

=除了作为赋值运算符还可以作为测试操作符

算术运算符

+  -  *  /  **  %(加 减 乘 除 乘方 取余)

使用expSEO靠我r进行运算,但目前只支持整数运算 expr  4 + 5 num2=`expr 4 + 5`

数字常量

使用下面的格式定义数字常量let "变量名=变量值" 变量值使用0开头为八进制 变量值使用0x开头为十SEO靠我六进制

双圆括号是let命令的简化

((a=10)) ((a++)) echo ((10+20))

9.各种特殊符号

引号

完全引用 不解释变量 " 非完全引用变量解释 ` 反引号 用于执行命令

圆括号()  (SEO靠我())  $()

单独使用圆括号会产生一个子shell   (xyz=123)数组初始化使用圆括号  IPS=(ip1 ip2 ip3)算数运算用到圆括号 echo $(( 19 + 20 ))命令的结SEO靠我果传给变量  cmd=$(ls)

[]   [[]]方括号做测试

单独使用方括号是测试(test)或数组元素功能

两个两个方括号表示测试表达式

<>尖括号,重定向符号

{}花括号

指定输出输出范围 echo {0SEO靠我..9} 文件复制 cp -v /etc/passwd{,.bak} 等价于cp -v /etc/passwd  /etc/passwd.bak

运算和逻辑符号

>  <  = 比较运算符

&& || ! SEO靠我 逻辑运算符(与或非)

其他符号

case 语句的分隔符要转义;; :   空指令 .   和source命令相同 ~   家目录 ,   分割目录 *   通配符   ?   条件测试或通配符 $   SEO靠我取值符号 |   管道符号 &   后台运行 _   空格 cd - 返回上一次操作的目录

10.测试与判断

退出命令和退出状态

exit命令用来退出执行的脚本

exit 10 返回10给shell 返回为0SEO靠我位不正常退出

$?  判断当前shell前一个进程是否正常退出测试命令test

test命令用于检查文件或比较值

test可以做以下测试:

文件测试

数字比较测试

字符串测试

test测试语句可以简化为[]符号

[]SEO靠我符号还有扩展写法[[]]支持&& 、 || 、<、>等逻辑判断man test  查询test命令的用法测试文件\字符串\整型数字 test -f /etc/passwd  如果文件存在且为普通文件则SEO靠我为真 if test -e ./bash thenecho 文件已存在! elseecho 文件不存在! fi echo $?(0存在 1不存在) --------------------------SEO靠我------------- [ -d  /etc/ ]#判断目录是否存在 --------------------------------------- //比较大小 -eq    等于则为真 -neSEO靠我    不等于则为真 -gt    大于则为真 -ge    大于等于则为真 -lt    小于则为真 -le    小于等于则为真 [ 5 -gt 4]  #5大于4 ---------------SEO靠我------------------------ #[[]] 支持各种特殊的逻辑符号 [[ 5 > 4 ]] --------------------------------------- #判断字符SEO靠我串是否相等 [ "abc" = "abc" ]

使用if命令进行各种逻辑判断

使用if-then语句if[测试条件成立] 或命令返回值是否为0 then 执行相应命令 fi结束if pwd  then eSEO靠我cho "pwd running" fi

使用if-then-else语句

if [ 测试条件成立 ] then 执行相应命令 else 测试条件不成,执行命令 fi结束if [ 测试条件成立 ] theSEO靠我n 执行相应命令 elif [ 测试条件成立 ] then 执行相应命令 else 测试条件不成立,执行相应命令 fi结束

嵌套if语句

if [ 测试条件成立 ] then 执行相应命令if [ 测试条SEO靠我件成立 ]then 执行相应命令fifi结束

11.分支语句

case语句和select语句可以构成分支,这个和C语言中的swich-case语法一样

case "$变量" in"情况1" )命令... ;SEO靠我;"情况2" )命令... ;;* )命令... ;;esac    case "$1" in"start"|"START")echo $0 start...;;"stop")echo $0 stopSEO靠我...;;)echo "others" esac

12.循环

for循环语句;使用for循环遍历命令的执行结果

for循环的语法for 参数  in 列表do 执行的命令 done 封闭一个循环

使用反引号或SEO靠我$()方式执行命令,命令的结果当做列表进行处理

for i in {1..9}  do echo hello  echo $i  done for filename in `ls *.mps` do SEO靠我echo ${filename} mv $filename $(basename $filename .mp3).mp4 done

列表中包含多个变量,变量用空格分割

对文本的处理,要使用文本查看命令取出SEO靠我文本内容

默认逐行处理,如果文本出现空格会当做多行处理

C语言风格的for命令for((变量初始化;循环判断条件;变量变化)) do循环执行的命令 donefor (( i=1 ; i<=10 ; i++SEO靠我)) doecho $idone

while循环

 while test测试条件是否成立 do命令 donewhile [ $a -lt 10] do((a++))echo $a done    whileSEO靠我: #死循环 doecho always done#until循环与while循环相反,循环测试为假时,执行循环,为真时循环停止 until [ 5 -lt 4] doecho hello done

bSEO靠我reak和continue语句

for sc_name in /etc/profile.d/*.sh doif [ -x $sc_name ] ; then. $sc_namefi donefor nuSEO靠我m in {1..9} doif [ $num -eq 5 ] ;thenbreakfiif [ $num -eq 6 ] ;thencontinuefi    done

使用循环对命令行参数的处理

命令SEO靠我行参数可以使用$1 $2 ...${10}..$n进行读取

$0 代表脚本名称

$*和$@代表所有的位置参数

$#代表位置参数的数量for pos in $* do if[ "$pos" = "help" SEO靠我]; thenecho $pos  done#shift 参数左移 while [ $#  -ge 1] doif [ "$1" = "help" ]; thenecho "do something"SEO靠我fishift done

12.函数

函数用于“包含”重复使用的命令集合

自定义函数#函数的定义 function fname(){ 命令 }#定义函数的调用执行 fname#定义函数作用范围的变量 locSEO靠我al 变量名#函数的参数  通过位置参数来获取传入函数的参数 $1 $2 $3checkpid() {local ifor i in $* ; do[ -d "/proc/$i" ] && returSEO靠我n 0donereturn 1   }

系统自建的函数

系统自建的函数库,可以在脚本中引用,系统自建的函数库在下面的文件中 /etc/init.d/functions

自建函数库

使用source函数脚本文件“SEO靠我导入” 函数 source /etc/init.d/function echo_sccess

13.脚本优先级

可以使用nice和renice调整脚本优先级

避免出现“不可控的”死循环

死循环导致cpu占用过高SEO靠我

死循环导致死机fork炸弹可以不停的创建子进程导致操作系统崩溃卡死  | : &后台创建进程 func() {func | func&}.() {.|.&};.ulimit -a #用户限制

14.信号通信SEO靠我

信号也是Shell脚本通信的一种方式,kill命令默认会发送15信号给应用程序,Ctrl+C发送2信号给应用程序。信号9不可以阻塞。所以我们可以通过kill -9来关闭对应的进程。

我们可以在脚本中捕获SEO靠我对应的信号 #!/bin/bash #捕获信号15和信号2 trap "echo sig 15" 15 trap "echo sig 2" 2 echo $$ while : do: done

发送信号给SEO靠我对应的shell进程

kill -15 pid

15.计划任务

一次性任务

添加一次性计划任务需要at模块,没有at模块需要安装 at sudo apt install at

配置对应的任务

at 18:31 ecSEO靠我ho hello > /tmp/hello.txt #Ctrl+D退出编辑 #非内部命令的话,指定完整的命令路径 #shell 脚本需要通过 source命令引入环境变量 #计划任务没有终端,需要重定SEO靠我向输出

使用atq查看作业

使用atrm  index  删除对应索引的作业

周期性计划任务

cron进行周期任务

配置周期性任务

crontab -e

查看现有的计划任务

crontab -l

crontab -e SEO靠我配置格式,最小时间是按分钟执行

分钟 小时 日期 月份 星期 执行的命令

注意命令的路径问题*用于匹配任意的* * * * * /usr/bin/date >> /tmp/date.txt #cd /vaSEO靠我r/log 查看cron查看定时任务日志 * * * * 1,5 /usr/bin/date >> /tmp/date.txt #星期一或星期五 * * * * 1-5 /usr/bin/date >SEO靠我> /tmp/date.txt  #星期一至星期五 15 18 * * 1 /usr/bin/date >> /tmp/date.txt  0 3 15 * * /usr/bin/date >> /tSEO靠我mp/date.txt  每月15日三点整执行任务

用户有自己的任务保存在/var/spool/cron目录下, 有用户同名的文件

延时任务

如果计算机不能按照预期时间运行,任务将会延时启动

anacontaSEO靠我b 延时计划任务 vim /etc/cron.d/0hourly  #配置按小时运行的延时任务 vim /etc/cron.d/anacrontab  #配置按日运行的延时任务

计划性任务加锁flock

fSEO靠我lock锁文件防止定时任务冲突,或者重复运行 flock -xn "/tmp/f.lock" -c "/root/a.sh"  #排他锁防止任务多次启动
“SEO靠我”的新闻页面文章、图片、音频、视频等稿件均为自媒体人、第三方机构发布或转载。如稿件涉及版权等问题,请与 我们联系删除或处理,客服邮箱:html5sh@163.com,稿件内容仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同 其观点或证实其内容的真实性。

网站备案号:浙ICP备17034767号-2