shell脚本语法详解

news2024/10/25 1:52:23

目录

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 "$@"; do
    echo "${parm}"
done

for parm in "$*"; do
    echo "${parm}"
done

运行结果

 其余预设变量

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

 代码实例

#!/bin/bash
function func1(){
#返回非0状态,表示func1函数执行出错
    return 1
}

function func2(){
#获取传递给func2的参数
    parm1=$1
    parm2=$2
    echo "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/bash

for item in `ls`; do
    if [ -d "$item" ]; then
        echo "$item 是一个目录"
    elif [ -f "$item" ]; then
        echo "$item 是一个普通文件"
    else
        echo "$item 是其他类型"
    fi
done

 

字符串测试

  • =:判断两个字符串是否相等
  • !=:判断两个字符串是否不相等
  • -z:判断是否是空串
  • -n:判断是否是非空串
#!/bin/bash

read -p "str1=" str1
read -p "str2=" str2

#如果str1和str2都不为空
if [[ ! -z ${str1} && ! -z ${str2} ]];then
    echo "$str1"
    echo "$str2"
#如果str1和str2的值相等
    if [ "$str1" = "$str2" ]; then
        echo "str1 equal str2"
    else
        echo "str1 not equal str2"
    fi
fi

 

数值测试

#!/bin/bash

read -p "num1=" num1
read -p "num2=" num2

if [ $num1 -eq $num2 ]; then
    echo "$num1 equal $num2"
elif [ $num1 -gt $num2 ];then
    echo "$num1 greater than $num2"
else
    echo "$num1 less than $num2 "
fi

 

控制语句

逻辑语句

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

条件语句

if语句

使用格式如下:

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

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

case语句

#!/bin/bash

read -p "please input choice yes or no >>> " choice

case $choice in
    yes | y* | Y*)
        echo "yes"
        ;;
    no | n* | N*)
        echo "no"
        ;;
    *)
        echo "others"
        ;;
esac

循环语句

for循环

#!/bin/bash

read -p "please input n is >>> " n
declare -i sum=0
declare -i i=0
for ((i=0;i<n;i++))
do
    sum=$sum+$i
done

echo "sum=$sum"

for item in `ls`; do
    if [ -d "$item" ]; then
        echo "$item 是一个目录"
    elif [ -f "$item" ]; then
        echo "$item 是一个普通文件"
    else
        echo "$item 是其他类型"
    fi
done

while循环

#!/bin/bash

read -p "请输入一个正整数: " n

while [ $n -gt 0 ]
do
    echo "当前数字是: $n"
    n=$((n - 1))
done

echo "循环结束!"

 

函数

函数定义

function 函数名(){
    函数体
}

函数的调用与返回

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

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

#!/bin/bash
function max(){
    if [ $1 -gt $2 ];then
        echo $1
    else
        echo $2
    fi
}

max_val=$(max $@)
echo "max num is $max_val"

然后在终端命令行输入

./test.sh 12 45

 执行结果如下所示

文件导入

定义一个max.sh文件

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

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

#!/bin/bash
#导入max.sh文件
source max.sh

read -p "num1=" num1
read -p "num2=" num2
#使用max.sh文件中的Max函数
max_val=$(Max $num1 $num2)
echo "max_val is $max_val"

终端命令行执行

参考

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2222866.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【HuggingFace 如何上传数据集 (2) 】国内网络-稳定上传图片、文本等各种格式的数据

【HuggingFace 下载】diffusers 中的特定模型下载&#xff0c;access token 使用方法总结【HuggingFace 下载中断】Git LFS 如何下载指定文件、单个文件夹&#xff1f;【HuggingFace 如何上传数据集】快速上传图片、文本等各种格式的数据 上文的方法因为是 https 协议&#xf…

CORS预检请求配置流程图 srpingboot和uniapp

首先要会判断预检请求 还是简单请求 简单请求 预检请求 #mermaid-svg-1R9nYRa7P9Pll4AK {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-1R9nYRa7P9Pll4AK .error-icon{fill:#552222;}#mermaid-svg-1R9nYRa7P9Pll4…

JAVA Maven 的安装与配置

一、下载地址 官方网站&#xff1a;Maven – Download Apache Maven 我这里是3.8.6版本 二、安装步骤 maven安装之前要先安装jdk&#xff0c;请确保你的系统已经安装了jdk环境。 1.将下载好的 Maven 进行解压 apache-maven-3.6.8-bin.zip 2.配置本地仓库:修改 conf/settin…

HDU RSA

翻译成中文后&#xff1a; 思路&#xff1a;由题易得&#xff0c;d * e y * f ( n ) 1 ,且gcd ( e , f ( n ) ) 1,所以用扩展欧几里得求出 d &#xff0c;但要保证 d 是非负的&#xff0c;最有用快速幂求出每个字符即可。 #include<bits/stdc.h> using namespace std;…

【Web前端概述】

HTML 是用来描述网页的一种语言&#xff0c;全称是 Hyper-Text Markup Language&#xff0c;即超文本标记语言。我们浏览网页时看到的文字、按钮、图片、视频等元素&#xff0c;它们都是通过 HTML 书写并通过浏览器来呈现的。 一、HTML简史 1991年10月&#xff1a;一个非正式…

第 6 章 Kafka-Eagle 监控 和 Kafka-Kraft 模式

Kafka-Eagle 框架可以监控 Kafka 集群的整体运行情况&#xff0c;在生产环境中经常使用。 6.1 MySQL 环境准备 Kafka-Eagle 的安装依赖于 MySQL &#xff0c; MySQL 主要用来存储可视化展示的数据。如果集 群中之前安装过 MySQL 可以跨过该步。 6.2 Kafka 环境准备 …

ELK日志分析系统部署

ELK日志分析系统 ELK指的是ElasticsearchLogstashKibana这种架构的缩写。 ELK是一种日志分析平台&#xff0c;在很早之前我们经常使用Shell三剑客&#xff08;一般泛指grep、sed、awk&#xff09;来进行日志分析&#xff0c;这种方式虽然也可以应对多种场景&#xff0c;但是当…

多线程初阶(七):单例模式指令重排序

目录 1. 单例模式 1.1 饿汉模式 1.2 懒汉模式 2. 懒汉模式下的问题 2.1 线程安全问题 2.2 如何解决 --- 加锁 2.3 加锁引入的新问题 --- 性能问题 2.4 指令重排序问题 2.4.1 指令重排序 2.4.2 指令重排序引发的问题 1. 单例模式 单例模式, 是设计模式中最典型的一种模…

CTFHUB技能树之SQL——MySQL结构

开启靶场&#xff0c;打开链接&#xff1a; 先判断一下是哪种类型的SQL注入&#xff1a; 1 and 11# 正常回显 1 and 12# 回显错误&#xff0c;说明是整数型注入 判断一下字段数&#xff1a; 1 order by 2# 正常回显 1 order by 3# 回显错误&#xff0c;说明字段数是2列 知道…

未来医疗:大语言模型如何改变临床实践、研究和教育|文献精析·24-10-23

小罗碎碎念 这篇文章探讨了大型语言模型在医学领域的潜在应用和挑战&#xff0c;并讨论了它们在临床实践、医学研究和医学教育中的未来发展。 姓名单位名称&#xff08;中文&#xff09;Jan Clusmann德国德累斯顿工业大学埃尔朗根弗雷斯尼乌斯中心数字化健康研究所Jakob Nikola…

html 轮播图效果

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

动态量化:大模型在端侧CPU快速推理方案

作为一款高性能的推理引擎框架&#xff0c;MNN高度关注Transformer模型在移动端的部署并持续探索优化大模型在端侧的推理方案。本文介绍权重量化的模型在MNN CPU后端的推理方案&#xff1a;动态量化。动态量化指在运行时对浮点型feature map数据进行8bit量化&#xff0c;然后与…

(gersemi) CMake 格式化工具

文章目录 &#x1f9ee;介绍&#x1f9ee;安装&#x1f9ee;使用&#x1f5f3;️模式 modes&#x1f5f3;️样式配置 config ⭐END&#x1f31f;help&#x1f31f;交流方式 &#x1f9ee;介绍 BlankSpruce/gersemi: A formatter to make your CMake code the real treasure A f…

Leetcode 最长公共前缀

java solution class Solution {public String longestCommonPrefix(String[] strs) {if(strs null || strs.length 0) {return "";}//用第一个字符串作为模板,利用indexOf()方法匹配,由右至左逐渐缩短第一个字符串的长度String prefix strs[0];for(int i 1; i …

【Java】反射概述与详解

目录 引言 一、概述 二、获取Class对象 三、反射获取构造方法 代码示例&#xff1a; 四、反射获取成员变量 代码示例&#xff1a; 五、反射获取成员方法 代码示例&#xff1a; 结语 引言 Java中的反射&#xff08;Reflection&#xff09;是一种强大的机制&#…

热门的四款PDF合并工具大比拼!!!

在现代的数字化办公环境中&#xff0c;PDF文件已经成为了一种重要的文件格式&#xff0c;用于保存和共享各种类型的文档。然而&#xff0c;有时候我们需要将多个PDF文件合并成一个文件&#xff0c;这时候就离不开好用的PDF合并工具了。选择一个好的PDF合并工具是一个长期的投资…

Python基于OpenCV的实时疲劳检测

2.检测方法 1&#xff09;方法 与用于计算眨眼的传统图像处理方法不同&#xff0c;该方法通常涉及以下几种组合&#xff1a; 1、眼睛定位。 2、阈值找到眼睛的白色。 3、确定眼睛的“白色”区域是否消失了一段时间&#xff08;表示眨眼&#xff09;。 相反&#xff0c;眼睛长…

【Power Query】List.Select 筛选列表

List.Select 筛选列表 ——在列表中返回满足条件的元素 List.Select(列表,判断条件) 不是列表的可以转成列表再筛选&#xff0c;例如 Record.ToList 不同场景的判断条件参考写法 (1)单条件筛选 列表中小于50的数字 List.Select({1,99,8,98,5},each _<50) (2)多条件筛…

红黑树(Java数据结构)

前言&#xff1a; 红黑树的学习需要大家对二叉搜索树与AVL树有深刻的理解&#xff0c;如果话没有看过我对二叉搜索树与AVL树的讲解的铁子们可以先看看上一篇文章&#xff1a;二叉搜索树与AVL树(java数据结构)-CSDN博客 红黑树&#xff1a; 什么是红黑树&#xff1f; 红黑树&a…

CenterTrack算法详解

背景&#xff1a; 早期追踪器在缺乏强的低水平线索下&#xff0c;容易失败检测后跟踪的模型依赖于检测器&#xff0c;且需要一个单独的阶段匹配关联策略的时间长 简介&#xff1a; 基于点的跟踪思想&#xff0c;通过预测目标的中心点来进行跟踪&#xff0c;同时实现检测与跟…