当前位置: 首页 > news >正文

shell脚本语法详解

目录

shell语法基础

指定shell解析器

注释

运行

 变量

定义变量

引用变量

清除变量值

从键盘获取值

输入单值

 添加输入提示语

读取多值

​编辑

定义只读变量

环境变量

设置环境变量与查看环境变量

特殊变量

三种引号的作用与区别

小括号与大括号

参数传递

位置参数传递

选项参数传递

获取参数相关信息

 其余预设变量

字符串处理

条件测试

文件测试

字符串测试

数值测试

控制语句

逻辑语句

条件语句

if语句

case语句

循环语句

for循环

while循环

函数

函数定义

函数的调用与返回

文件导入


shell语法基础

指定shell解析器

#!/bin/bash

#!用来声明脚本由什么shell解释,否则使用默认shell

shell终端有多种,我们大部分用的是sh或者bash,其中sh是最原始的shell,而bash不完全兼容sh,查看系统可用的shell终端可用以下命令

 vim /etc/shells
/bin/sh
/bin/bash
/bin/rbash
/bin/dash
/usr/bin/tmux
/usr/bin/screen

注释

#

运行

shell脚本有三种执行方式

  • ./xxx.sh
    • ./xxx.sh :先按照 文件中#!指定的解析器解析

      如果#!指定指定的解析器不存在 才会使用系统默认的解析器

  • bash xxx.sh
    • bash xxx.sh:指明先用bash解析器解析

      如果bash不存在 才会使用默认解析器

  • . xxx.sh 
    •  直接使用默认解析器解析(不会执行第一行的#!指定的解析器)但是第一行还是要写的

三种执行情况:

打开终端就会有以后个解释器,我们称为当前解释器

我们指定解析器的时候(使用 ./xxx.sh 或 bash xxx.sh)时会创建一个子shell解析 脚本

 变量

定义变量

变量名=变量值
如:num=10

引用变量

$变量名

清除变量值

unset 

从键盘获取值

read命令可以从键盘获取值

输入单值

#!/bin/bash
echo "--------"
read data
echo "data=$data"

运行结果

 添加输入提示语

使用read命令的-p选项可以添加输入提示语

#!/bin/bash
echo "--------"
read -p "please input the value of data:" data
echo "data=$data"

读取多值

#!/bin/bash
read -p "please input the value of data1 and data2 >>> " data1 data2
echo "data1 is ${data1} and the data2 is ${data2}"

注意,输入时以空格作为分隔符,运行结果如下: 

定义只读变量

readonly关键字可标识一个变量为只读变量 

#!/bin/bash
readonly num=10
echo "num=$num"
num=20
echo "after num=$num"

环境变量

设置环境变量与查看环境变量

创建一个test.sh脚本,并写下

#!/bin/bash
export MY_DATA=42

退出保存,然后在终端中输入

 source ./test.sh

然后在终端中输入

上述过程解析

  • export关键字用于定义一个环境变量
  • source命令用于将脚本中的环境变量生效,生效后的作用就是让其他脚本可识别该变量
    • 因此,假如我们重新定义一个新的脚本,输入echo MY_DATA,是可以输出该值的
  • env命令用于列出所有的环境变量 

特殊变量

三种引号的作用与区别

  • 双引号:可以解析变量的值
  • 单引号:不能解析变量的值,直接将单引号中的内容作为字符串处理
  • 反引号(数字键1前的按键):引用系统命令
#!/bin/bash
num=42
echo "num=$num"
echo 'num=$num'#直接将$num作为字符串处理。并不会解析num的值echo "date is `date`"

上述代码的运行结果如下所示

小括号与大括号

  • ():由子shell完成,不会影响当前shell的值
  • {}:由当前shell完成,通常用于作为变量引用的边界
#!/bin/bash
data=42
(
#以下内容由子shell完成,不会影响外边data的值
data=43
echo "内部data值为:$data"
)echo "外部data值为:$data"
#使用{}将data变量的引用与外部的eee三个字符区分开
echo "${data}eee"
echo ">>>>>>>"
echo "$dataeee"

运行结果

因此,一个好的习惯应当是,在引用变量的时候,使用{}将其包裹 

参数传递

位置参数传递

shell中用$1、$2、$3来传递外部的第一个参数、第二个参数、第三个参数等等,该参数传递方式称为位置参数传递

创建一个test.sh脚本,内容定义如下

#!/bin/bash
echo "第一个参数值:$1"
echo "第二个参数值:$2"
echo "第三个参数值:$3"

 保存退出,在命令行中执行脚本,并传递参数

./test.sh 42 43 45

运行结果为

选项参数传递

如果想实现选项参数传递,而不依赖于位置,可参考

shell脚本实现长短项参数设置_shell脚本处理长参数-CSDN博客

获取参数相关信息

  • $#:获取传入的参数个数
  • $@:获取所有的参数内容,其中每个参数都会作为独立的字符串处理,假设输入参数是 one two three,使用 "$@" 会得到 "one""two""three" 三个独立的参数。
  • $*:获取所有的参数内容,并将所有参数作为一个整体处理。输入参数 one two three,使用 "$*" 会得到 "one two three",成为一个单一字符串。
#!/bin/bash
echo "第一个参数值:$1"
echo "第二个参数值:$2"
echo "第三个参数值:$3"
echo "the number of all parms is: $#"
echo "all parms value is: $@"
echo "all parms value is: $*"for parm in "$@"; doecho "${parm}"
donefor parm in "$*"; doecho "${parm}"
done

运行结果

 其余预设变量

  • $?:获取命令执行后返回的状态,0表示执行成功,无错误,非0表示执行失败,有错误
  • $0:获取当前执行的进程名
  • $$:获取当前执行的进程号

 代码实例

#!/bin/bash
function func1(){
#返回非0状态,表示func1函数执行出错return 1
}function func2(){
#获取传递给func2的参数parm1=$1parm2=$2echo "parm1 is ${parm} and the parm2 is ${pamr2}"#返回0,表示func2函数执行无误return_value="yes"echo ${return_value}return 0
}func1
echo "func1 return status is $?"func2 42 43
echo "func2 return status is $?"return_value=$(func2 54 56)
echo "func2 return status is $? ,and the return value is $return_value"

上述代码解析:

  • function关键字用于定义一个函数
  • shell中的return关键字是返回函数执行状态的,return后的值只能是数字,不能是其余字符串信息
  • 如果想返回函数体内的值给函数外部执行者,使用echo命令
  • shell中函数参数的传递,同样也使用上述的位置参数传递

执行结果

获取进程名与进程号

#!/bin/bash
echo "process name is $0"
echo "process number is $$"

字符串处理

#!/bin/bash
str="hello hello world"#获取
echo "字符串长度:${#str}"#从下标为3的字符开始截取子串
echo "${str:3}"#从下标为3的字符开始截取长度为4的子串
echo "${str:3:4}"#将字符串中的第一个hello替换为hahaha
new_str="${str/hello/hahaha}"
echo "$new_str"#将字符串中的所有hello替换为hhhhh
new_str1="${str//hello/hhhhh}"
echo "$new_str1"

条件测试

条件测试使用[ condition ]判断condition是否为真

使用方括号时,要注意在条件两边加上空格,同时,运算符和操作数之间必须有空格。缺少空格会导致语法错误。

文件测试

判断文件状态

  • -e:判断文件是否存在
  • -d:判断文件是否是一个目录
  • -f:判断文件是否是一个文件
  • -s:判断文件是否非空
  • -r:判断文件是否可读
  • -w:判断文件是否可写
  • -x:判断文件是否可执行
  • -L:判断该文件是否是符号链接
  • -c:判断是否是字符设备
  • -b:判断是否是块设备
#!/bin/bashfor item in `ls`; doif [ -d "$item" ]; thenecho "$item 是一个目录"elif [ -f "$item" ]; thenecho "$item 是一个普通文件"elseecho "$item 是其他类型"fi
done

 

字符串测试

  • =:判断两个字符串是否相等
  • !=:判断两个字符串是否不相等
  • -z:判断是否是空串
  • -n:判断是否是非空串
#!/bin/bashread -p "str1=" str1
read -p "str2=" str2#如果str1和str2都不为空
if [[ ! -z ${str1} && ! -z ${str2} ]];thenecho "$str1"echo "$str2"
#如果str1和str2的值相等if [ "$str1" = "$str2" ]; thenecho "str1 equal str2"elseecho "str1 not equal str2"fi
fi

 

数值测试

#!/bin/bashread -p "num1=" num1
read -p "num2=" num2if [ $num1 -eq $num2 ]; thenecho "$num1 equal $num2"
elif [ $num1 -gt $num2 ];thenecho "$num1 greater than $num2"
elseecho "$num1 less than $num2 "
fi

 

控制语句

逻辑语句

  • 与运算:&&
  • 或运算:||
  • 非运算:!

条件语句

if语句

使用格式如下:

if [条件1]; then执行第一段程序
elif [条件2];then
执行第二段程序
else执行第三段程序
fi

结合上述字符串测试与数值测试案例学习即可

case语句

#!/bin/bashread -p "please input choice yes or no >>> " choicecase $choice inyes | y* | Y*)echo "yes";;no | n* | N*)echo "no";;*)echo "others";;
esac

循环语句

for循环

#!/bin/bashread -p "please input n is >>> " n
declare -i sum=0
declare -i i=0
for ((i=0;i<n;i++))
dosum=$sum+$i
doneecho "sum=$sum"

for item in `ls`; doif [ -d "$item" ]; thenecho "$item 是一个目录"elif [ -f "$item" ]; thenecho "$item 是一个普通文件"elseecho "$item 是其他类型"fi
done

while循环

#!/bin/bashread -p "请输入一个正整数: " nwhile [ $n -gt 0 ]
doecho "当前数字是: $n"n=$((n - 1))
doneecho "循环结束!"

 

函数

函数定义

function 函数名(){函数体
}

函数的调用与返回

函数的调用和平时调用命令一样

写一个test.sh脚本,并定义文件内容如下: 

#!/bin/bash
function max(){if [ $1 -gt $2 ];thenecho $1elseecho $2fi
}max_val=$(max $@)
echo "max num is $max_val"

然后在终端命令行输入

./test.sh 12 45

 执行结果如下所示

文件导入

定义一个max.sh文件

#!/bin/bash
function Max(){if [ $1 -gt $2 ];thenecho $1elseecho $2fi
}

然后再定义一个main.sh文件

#!/bin/bash
#导入max.sh文件
source max.shread -p "num1=" num1
read -p "num2=" num2
#使用max.sh文件中的Max函数
max_val=$(Max $num1 $num2)
echo "max_val is $max_val"

终端命令行执行

参考

shell脚本语言(超全超详细) - 知乎

相关文章:

shell脚本语法详解

目录 shell语法基础 指定shell解析器 注释 运行 变量 定义变量 引用变量 清除变量值 从键盘获取值 输入单值 添加输入提示语 读取多值 ​编辑 定义只读变量 环境变量 设置环境变量与查看环境变量 特殊变量 三种引号的作用与区别 小括号与大括号 参数传递 位…...

2021亚洲机器学习会议:面向单阶段跨域检测的域自适应YOLO(ACML2021)

原文标题&#xff1a;Domain Adaptive YOLO for One-Stage Cross-Domain Detection 中文标题&#xff1a;面向单阶段跨域检测的域自适应YOLO 1、Abstract 域转移是目标检测器在实际应用中推广的主要挑战。两级检测器的域自适应新兴技术有助于解决这个问题。然而&#xff0c;两级…...

面试题:描述在前端开发中,如何利用数据结构来优化页面渲染性能,并给出一个具体的示例。

在前端开发中&#xff0c;优化页面渲染性能是提升用户体验的关键之一。合理地使用数据结构可以有效地减少DOM操作的次数、提高数据处理的效率&#xff0c;从而加快页面的渲染速度。以下是一些策略&#xff0c;并给出一个具体的示例。 1. 使用合适的数据结构 数组与对象&#…...

微积分复习笔记 Calculus Volume 1 - 3.2 he Derivative as a Function

3.2 The Derivative as a Function - Calculus Volume 1 | OpenStax...

html 轮播图效果

轮播效果&#xff1a; 1、鼠标没有移入到banner,自动轮播 2、鼠标移入&#xff1a;取消自动轮播、移除开始自动轮播 3、点击指示点开始轮播到对应位置 4、点击前一个后一个按钮&#xff0c;轮播到上一个下一个图片 注意 最后一个图片无缝滚动&#xff0c;就是先克隆第一个图片…...

Android Room(SQLite) too many SQL variables异常

SQLiteException 一、解决办法1. 修改数据库语句2. 分批执行 二、问题根源 转载请注明出处: https://blog.csdn.net/hx7013/article/details/143198862 在使用 Room 或其他基于 SQLite 的 ORM 框架时&#xff0c;批量操作如 IN 或 NOT IN 查询可能会触发 android.database.sqli…...

sentinel原理源码分析系列(八)-熔断

限流为了防止过度使用资源造成系统不稳&#xff0c;熔断是为了识别出”坏”资源&#xff0c;避免好的资源受牵连(雪崩效应)&#xff0c;是保证系统稳定性的关键&#xff0c;也是资源有效使用的关键&#xff0c;sentinel熔断插槽名称Degrade(降级)&#xff0c;本人觉得应该改为熔…...

安全见闻(4)——开阔眼界,不做井底之蛙

内容预览 ≧∀≦ゞ 安全见闻四&#xff1a;操作系统安全机制深度解析声明操作系统机制1. 注册表2. 防火墙3. 自启动与计划任务4. 事件日志5. 内核驱动与设备驱动6. 系统服务7. 进程与线程8. 系统编程 从操作系统机制看病毒设计1. 自启动&#xff1a;病毒如何在系统启动时运行&a…...

(二十二)、k8s 中的关键概念

文章目录 1、总体概览2、第一层&#xff1a;物理机、集群、Node、Pod 之间的关系2、第二层&#xff1a;命名空间 Namespace3、定义4、控制平面&#xff08;Control Plane&#xff09;5、特别的概念 Service6、Deployment 经过 之前几篇文章对 k8s 的实践&#xff0c;结合实践&…...

python基础综合案例(数据可视化-地图可视化)

1.基础地图使用 注意写名字的时候要写全名&#xff0c;比如上海市不能写出上海&#xff0c;不然看不到数据 鼠标点击即可看到数据 设置属性的时候不要忘记导包 # 演示地图可视化的基础使用 from pyecharts.charts import Map from pyecharts.options import VisualMapOpts # 准…...

基于SpringBoot足球场在线预约系统的设计与实现

&#x1f497;博主介绍&#x1f497;&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示&#xff1a;文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…...

操作系统笔记(二)进程,系统调用,I/O设备

什么是进程? 一个正在执行的程序一个包含运行一个程序所需要的所有信息的容器进程的信息保存在一个进程表中( Process Table)。进程表中的每一项对应一个进程,称为进程控制块(Process control block,PCB)。 PCB信息包括: 用户ID(UID)、进程ID(PID)…...

DevOps实践:在GitLab CI/CD中集成静态分析Helix QAC的工作原理与优势

基于云的GitLab CI/CD平台使开发团队能够简化其CI/CD流程&#xff0c;并加速软件开发生命周期&#xff08;SDLC&#xff09;。 将严格的、基于合规性的静态分析&#xff08;如Helix QAC所提供&#xff09;作为新阶段添加到现有的GitLab CI/CD流程中&#xff0c;将进一步增强SD…...

前端面试题-token的登录流程、JWT

这是我的前端面试题的合集的第一篇&#xff0c;后面也会更新一些笔试题目。秋招很难&#xff0c;也快要结束了。但是&#xff0c;不要放弃&#xff0c;一起加油^_^ 一、token的登录流程 1.客户端用账号密码请求登录 2.服务端收到请求&#xff0c;需要去验证账号密码 3.验证成…...

【软考高级架构】关于分布式数据库缓存redis的知识要点汇总

一.分布式数据库的含义 分布式数据库缓存指的是在高并发的环境下&#xff0c;为了减轻数据库的压力和提高系统响应时间&#xff0c;在数据库系统和应用系统之间增加一个独立缓存系统。 二.常见的缓存技术 &#xff08;1&#xff09;MemCache: Memcache是一个高性能的分布式的内…...

构建自然灾害预警决策一体化平台,筑牢工程安全数字防线

近年来&#xff0c;国家和部委也强调了要切实加强地质灾害监测预警。作为国内智慧应急领域的先行者&#xff0c;Mapmost持续探索利用数字孪生技术&#xff0c;推进自然灾害风险预警精细化&#xff0c;强化对监测数据的综合分析和异常信息研判处置。建立健全区域风险预警与隐患点…...

随机题两题

逆序对 题目 给定一个数组&#xff0c;求其中有多少逆序对&#xff0c;要求时间复杂度不超过nlogn。 思路 使用归并排序的分治思想&#xff0c;将数组递归地分为左右两部分。在合并两个有序子数组时&#xff0c;若左侧数组中的某个数大于右侧数组中的某个数&#xff0c;则可…...

信息安全工程师(69)数字水印技术与应用

前言 数字水印技术是一种在数字媒体中嵌入特定信息的技术&#xff0c;这些信息可以是版权信息、元数据等。 一、数字水印技术的定义与原理 数字水印技术&#xff08;Digital Watermarking&#xff09;是将一些标识信息&#xff08;即数字水印&#xff09;直接嵌入数字载体&…...

知识点框架笔记3.0笔记

如果基础太差&#xff0c;搞不清基本交规的&#xff08;模考做不到60分&#xff09;&#xff0c;建议找肖肖或者小轩老师的课程看一遍&#xff0c;内容差不多&#xff08;上面有链接&#xff09;&#xff0c;笔记是基于肖肖和小轩老师的科目一课程以及公安部交管局法规&#xf…...

Android组件化开发

Android组件化开发 组件化开发概念组件化开发的由来组件化开发有什么优势?组件化开发如何拿到入口参数?如何解决相同资源文件名合并的冲突?模式切换,如何使APP在单独调试跟整体调试自由切换?多个Module之间如何引用一些共同的library以及工具类?我们如何实现依赖关系及组…...

centos-LAMP搭建与配置(论坛网站)

文章目录 LAMP简介搭建LAMP环境安装apache&#xff08;httpd&#xff09;安装mysql安装PHP安装php-mysql安装phpwind LAMP简介 LAMP是指一组通常一起使用来运行动态网站或者服务器的自由软件名称首字母缩写&#xff1a;Linux操作系统&#xff0c;网页服务器Apache&#xff0c;…...

Python 实现日期计算与日历格式化输出

目录 一、引言 二、需求分析 三、实现思路 四、代码实现 五、代码分析 六、测试与验证 七、总结与展望 在日常的编程中&#xff0c;我们经常会遇到与日期相关的问题&#xff0c;比如计算两个日期之间的天数差、确定某个特定日期是星期几以及格式化输出日历等。本文将详细…...

npm install 安装很慢怎么办?

安装源管理器nrm sudo npm install -g nrm #macOSnpm install -g nrm #Windows以管理员身份运行 安装完毕之后通过以下命令可以切换你想要的源 nrm ls #查看源列表* npm ---------- https://registry.npmjs.org/yarn --------- https://registry.yarnpkg.com/tencent ------…...

【WRF数据处理】基于GIS4WRF插件将geotiff数据转为tiff(geogrid,WPS所需数据)

【WRF数据处理】基于GIS4WRF插件将geotiff数据转为tiff&#xff08;geogrid&#xff0c;WPS所需数据&#xff09; 数据准备&#xff1a;以叶面积指数LAI为例QGis实操&#xff1a;基于GIS4WRF插件将geotiff数据转为tiff警告&#xff1a;GIS4WRF: Input layer had an unexpected …...

python+大数据+基于Hadoop的个性化图书推荐系统【内含源码+文档+部署教程】

博主介绍&#xff1a;✌全网粉丝10W,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业毕业设计项目实战6年之久&#xff0c;选择我们就是选择放心、选择安心毕业✌ &#x1f345;由于篇幅限制&#xff0c;想要获取完整文章或者源码&#xff0c;或者代做&am…...

修改huggingface的缓存目录以及镜像源

执行以下语句查看当前配置 huggingface-cli env默认输出应该如下 (py39-transformers) PS D:\py_project\transformers_demo> huggingface-cli envCopy-and-paste the text below in your GitHub issue.- huggingface_hub version: 0.26.1 - Platform: Windows-10-10.0.22…...

散列表:如何解决哈希表装载因子过高导致的性能下降问题?

散列表:如何解决哈希表装载因子过高导致的性能下降问题? 当哈希表装载因子过高时,会导致性能下降,可以通过以下几种方法来解决: 一、扩容哈希表 (一)原理 当装载因子超过一定阈值时,增加哈希表的大小,然后将现有的元素重新哈希到新的哈希表中。这样可以降低装载因…...

Vue Router进阶学习

各位程序员1024节日快乐~ Vue Router 是 Vue.js 的官方路由管理器&#xff0c;它和 Vue.js 的核心深度集成&#xff0c;让构建单页面应用&#xff08;SPA&#xff09;变得简单。以下是 Vue Router 的基本用法 Vue Router 基本用法 安装 Vue Router 首先&#xff0c;你需要安…...

Linux巡检利器xsos的安装和使用

一、 一般项目基本完成的时候&#xff0c;后期运维工作的重点就是及时的&#xff0c;合理的频率巡检了&#xff0c;巡检的目的主要是及时发现各种各样的问题 那么&#xff0c;自己编写shell脚本是大部分人的第一选择&#xff0c;这里有个比较麻烦的地方&#xff0c;shell脚本…...

Django+Vue项目搭建

一、使用脚手架工具搭建项目 使用脚手架工具搭建Vue项目是一个快速且高效的方式&#xff0c;它能够帮助开发者自动配置好项目所需的环境和依赖。 一、安装Node.js和npm 1、下载Node.js&#xff1a; 前往Node.js官网下载并安装最新版本的Node.js。Node.js是一个基于Ch…...

自建网站主题及策划/国内做网站比较好的公司

note: within this loop 注意&#xff1a;在这个循环中 段错误 您的程序发生段错误&#xff0c;可能是数组越界&#xff0c;堆栈溢出&#xff08;比如&#xff0c;递归调用层数太多&#xff09;等情况引起 改正 把arr[20] 改成arr[21] #include<iostream> using namesp…...

代运营骗局/优化营商环境心得体会

前言if else 是我们写代码时&#xff0c;使用频率最高的关键词之一&#xff0c;然而有时过多的 if else 会让我们感到脑壳疼&#xff0c;例如下面这个伪代码&#xff1a;是不是很奔溃&#xff1f;虽然他是伪代码&#xff0c;并且看起来也很夸张&#xff0c;但在现实中&#xff…...

深圳工业设计展2024/深圳网站营销seo电话

正则表达式匹配&#xff0c;其中&#xff1a; * ~ 为区分大小写匹配 * ~* 为不区分大小写匹配 * !~和!~*分别为区分大小写不匹配及不区分大小写不匹配 文件及目录匹配&#xff0c;其中&#xff1a; * -f和!-f用来判断是否存在文件 * -d和!-d用来判断是否存在目录 * -e和!-e…...

网站建设知名公司/成人营销管理培训班

类似于上面这个问题&#xff1f;知道 f1 返回数据是什么吗&#xff1f; 在操作台上&#xff0c;掉用f1这个函数&#xff0c;为什么是函数那&#xff1f;下面跟大家讲 1、先看代码&#xff0c;代码上是一个函数内&#xff0c;定义了&#xff0c;一个空数组&#xff0c;一个循环…...

建设人才信息网是什么网站/南宁网站公司

文章目录1.1 为什么要过渡到IPv6原因1&#xff1a;IPv4地址耗尽原因2&#xff1a;让只使用IPv6的客户访问原因3&#xff1a;提升性能原因4&#xff1a;加固当前的网络。1.2 IPv6的历史1.3 IPv6的优点1.极大扩展的地址空间:2.无状态自动配置3.消除了NAT/PAT&#xff08;网络地址…...

昆山高端网站建设公司哪家好/茶叶网络营销策划方案

w ^ 我个人对卷积的理解&#xff1a; 卷积是一种对一个目标的一组参数中我们已经得知其中部分我们需要的参数特征&#xff0c;进而需要得到这组参数全部特征的计算方法&#xff0c;来源&#xff1a;泛函分析褶积。 卷积这个概念最早用在图像信号处理上&#xff0c;所以会出现…...