Linux学习笔记之七(shell脚本的基本语法)

Shell

  • 1、Shell脚本
  • 2、常用运算符
  • 2、特殊语法
  • 4、关于变量的一些命令
    • 4.1、echo
    • 4.2、export
    • 4.3、read
    • 4.4、declare/typeset
    • 4.5、local
    • 4.6、unset
  • 5、基本逻辑语法
    • 5.1、if判断
    • 5.2、for循环
    • 5.3、while循环
    • 5.4、case语句
  • 6、函数定义
  • 7、多脚本链接

1、Shell脚本

学习shell脚本开发之前,必须得有一些基础的Linux相关知识,比如环境变量和shell指令的等内容。
了解Linux的系统环境变量和shell命令可以看看我之前发过的两篇文章。
Shell命令(Linux操作命令笔记)
Linux学习笔记之二(环境变量)

再说回shell脚本和shell命令,简单来说,我们在Linux终端中敲下的大多数指令都是shell指令,比如cd , ls, pwd之类的。而 shell脚本就是在一个文件中把这些shell指令依次写在一起,然后让其自动依次执行。这样我们就不需要在终端一条条的去执行了。来看个例子吧。
例程目的:我想切换到$HOME/target目录,并且列出target目录下的所有文件。
首先我先新建一个test.sh的文件,然后往里面写入对应的shell指令。shell脚本文件的第一句话必须是:

#! /bin/bash

写这句话相当于在告诉Linux系统,我写的这个文件是shell脚本,请用bash解释器来解释这个脚本。
在这里插入图片描述
最后执行这个脚本就可以看到我target文件夹下的所有文件了。
在这里插入图片描述
常用的shell指令不妨移步

2、常用运算符

等于号

-eq
note: equal

不等号

-ne
note: not equal

大于号

-gt
note: greater than

大于或等于号

-ge
note: greater than or equal to

小于号

-lt
note: less than

小于等于号

-le
note: less than or equal to

逻辑与

-a
eg: [ $a -eq $b -a $a -eq $c ]		#a等于b于a等于c

逻辑或

-o
eg: [ $a -eq $b -o $a -eq $c ]		#a等于b或a等于c

比较运算符号大概就这些,note后面是缩写符号的整体意思,希望能够帮助记忆。但一点需要值得注意,以上这些特殊字符之用于判断整数与整数之间的关系,而不能用于判断字符串。如果想要判断字符串还得用 = = == == ! = != !=号这些,同时这些常规符号也兼容整数判断。至于逻辑运算符则也可以用&&, ||代替上述的-a和-o。
下面举几个例子来看一下-eq和 = = == ==的区别。

name="lihua"
age=18
[ "$name" -eq "lihua" ];[ "$name" == "lihua" ];[ "$age" == 18 ];

此外,在用$符号对变量取值的时候,最后还是加上一对双引号,这样可以避免很多错误。比如下面这个例子:

name="li hua"
[ $name == "li hua" ][ "$name" == "li hua" ]

如果不加双引号,那$name等于li hua,第一条语句就变成了下面这个样子,显然会报错。

li hua == "li hua"

加了引号就变成。

"li hua" == "li hua"

并且加引号只是把这个变量视为一个整体。但是凡被括号括起来的数据,都会被转化为数据串类型。。。
那么再提一句,如果想把字符串转化为整形,可以利用双括号的作用。

var="05"
num=$((var))
echo $num

2、特殊语法

  • -r:判断给定文件是否是可读文件。
  • -w:判断给定文件是否是可写文件。
  • -x:判断给定文件是否是可执行文件。
  • -d:判断给定参数是否是一个文件夹。
  • -f:判断给定参数是否是一个文件。
  • -s:判断一个文件是否存在并且是否非空。
  • -z:判断给定的字符串是否为空字符串。
  • -n:判断给定的字符串是否为非空字符串。

以上这些都是一些常见的单选项标记符。判断为真则返回1,否则返回。常用于if语句中,比如我们想判断home目录下的object_file是不是可执行文件,可以做如下操作。

if [ -x $HOME/object_file ];then
	echo "it is a execuate file"
fi

除了以上这些特殊标记符,还有许多特殊状态变量,如下:

  • $0:获取文件名
  • $n:获取输入的第n个参数
  • $?:获取上一条命令执行的结果,任何bash语句执行结果只有两种,执行成功为0,否则非0。
  • $#:获取传递的参数的总个数。
  • $*:获取脚本所有参数,加引号则表示“$1 $2 … $n ”。
  • $@:获取脚本所有参数,加引号则表示" $1 “,” $2 “,” $n "。 常用于for循环读取参数。
  • $!:获取上一个进程的pid号。
  • $$:获取当前shell脚本的pid号。
  • $_:获取上一次命令的最后一个参数。

看来$ 这个符号在Linux中还挺重要的,个人感觉它有点”取值“的意味,我们取一个变量也会用到$, 比如 $variable 。
最后我写一个脚本把这些特殊状态变量都用上,来看看以上这些特殊变量到底怎么用的。
在这里插入图片描述
执行一下看看效果:
在这里插入图片描述

4、关于变量的一些命令

下面介绍一些出现频率比较高的命令,但我仅讲一些常见的应用,不求全面详细。

4.1、echo

echo常用于打印变量。可以选择是否添加e和n参数,前者使echo可以识别转移字符,后者让echo打印之后不换行(echo默认打印后换行)。
举几个例子:

echo "hello"
echo -e "hello\n"		#可以识别\n
echo -n "hello"			#打印后不换行
echo -en "hello\t"		#识别转义字符且不换行
echo -ne "hello\t"		#效果同上

从上面例子可以看出,echo的参数可以自由组合,且不必考虑顺序,实现效果叠加。其他命令也同样可以。

4.2、export

export可以将变量转化成环境变量,所以我们经常在配置环境变量的时候用到这个命令。

export PATH=$PATH:$HOME/

4.3、read

在shell脚本中使用read命令正如在C语言中使用scanf命令或在python中使用input一样,可以获取用户的输入字符串。它可选的两个参数有p和t两个参数,前者可以显示提示符,后者可以设置等待用户输入的时间。
上个例子,这里我编写一个read.sh的脚本。

#! /bin/bash


read -p "please enter a number: " num_1

read -p "please enter another number: " -t 5 num_2

echo -e "\nthe first number is $num_1"

if [ -n "$num_2" ];then
        echo "the second number is $num_2" 
else
        echo "there is no the second number"
fi

接着,我故意第二个参数不输入,我们来看看结果。
在这里插入图片描述

4.4、declare/typeset

declare和typeset的功能基本一样,所以这里只说declare。
由于shell和python一样,都是弱定义型语言,即变量的类型取决于它所接受到值的类型,无需提前规定好。但弱定义偶尔也有一些不好地方,比如我们本来希望它是一个整型变量,它却因各种原因变成字符串类型。比如read会把数字也视为字符串。。
而declare的主要作用就是声明变量类型,让变量的类型不至于”跑偏“。它常用的参数有以下这些:

  • -a:将变量定义成数组类型。
  • -i:将变量定义成整数类型。
  • -x:将变量定义成环境变量。
  • -r:将变量定义为只读变量,同时该变量无法被unset。

看个例子:

declare -i num				
read -p "please enter a number: " num

这样就可以保证num这个变量就是一个整型了。
再来看看数组怎么用:

#! /bin/bash

declare -a num
read -p "please enter a number: " num[0]
read -p "please enter another number: " -t 5 num[1]
echo -e "\nthe first number is ${num[0]}"
if [ -n "$num[1]" ];then
        echo "the second number is ${num[1]}" 
else
        echo "there is no the second number"
fi

其实还是用[ ]来索引数组里面的值,但由于$的优先级高于[ ],所以记得用{ }来使num先索引再取值。除了用declare定义,我们也可以用弱定义的方式定义一个固定长度的数组。

num[0]=1
num[1]=2
..

4.5、local

声明一个变量是一个局部变量,由于shell语言中不同于大多数程序语言,在其函数内部声明的变量不会被自动视为局部变量。所以有时候为了使函数中的变量是局部变量就会用到local命令。
比如下面这个例子,在test这个函数内声明了一个var的局部变量,如果在函数外打印它就会报错。

#! /bin/bash

function test{
	local var=1
}

echo "$var"

4.6、unset

unset就比较简单了,其功能是删除一个变量。如下,删除var变量之后再调用echo是会报错的。

#! /bin/bash

var="test"
unset var
echo "$var"

看到unset便自然的想到是否有set,其实是有的,只不过它们的功能大相径庭,set主要用于显示所有环境变量。所以与unset相反的作用的更像是typeset。

5、基本逻辑语法

5.1、if判断

基本用法如下,注意该空格的地方不能省略,不该空格的地方不能多加。

#! /bin/bash

age=18
if [ "$age" -gt 18 ];then
	echo "adult"
else
	echo "child"
fi

在shell脚本中的中括号的主要用于条件测试,我们在看看if和逻辑预算符号一起使用的例子。

#! /bin/bash

age=21
if [ "$age" -eq 18 ] && [ "$age" -lt 20 ];
then
    echo "yes"
else
    echo "no"
fi

5.2、for循环

#! /bin/bash

for i in {1..4};
do
	echo "$i"
done

shell中的大括号用处挺多的,但这里的大括号表示生成一系列可能的集合,即1,2,3,4。另外,在也可借助双引号的能力来像C语言那样实现从1到4的遍历。

for((i=1; i<=4; i++));
do
	echo "$i"
done

5.3、while循环

#! /bin/bash

counter=0
while [ "$counter" -le 5 ]
do
    echo "Counter: $counter"
    ((counter++))
done

counter++外面必须包裹两个小括号,因为双括号用于逻辑运算和数学操作。

5.4、case语句

fruit="apple"

case "$fruit" in
    "apple")
        echo "You chose an apple.";;
    "banana")
        echo "You chose a banana.";;
    "orange"|"grape")
        echo "You chose an orange or a grape.";;
    *)
        echo "You chose something else.";;
esac

其中,“ * ) ”表示默认。在这里指如果fruit不是apple, banana, orange, grape其中一个就执行 “ * ) ”之后的操作。

6、函数定义

shell中的函数定义就比较奇怪了,主要体现在参数传输这一块。我们可以直接看看代码。

#! /bin/bash

function name()
{
    name="$1"
    age="$2"
    echo "his name is $name"
    echo "his age is $age"
}

name "xaioming" "18"

可以看到,上述例程所定义的函数之前有一个function的关键字,但其实这个是可有可无的。其次,可以用"$1"之类的符号来获得传入的参数。另外,即便调用该函数的时候传入了两个参数,但只拿除一个来用也无所谓。

#! /bin/bash

name()
{
    name="$1"
    #age="$2"
    echo "his name is $name"
    #echo "his age is $age"
}

name "xaioming" "18"

还有几点需要注意的,其一就是shell脚本和python一样,调用该函数必须在该函数定义之后。其二,在函数里面定义的变量如何不用local声明,那么是会被认为是全局变量的,这样可能会照成很多麻烦。

7、多脚本链接

前面提到shell脚本的编写逻辑和python有点像,调用函数之前必须在先定义函数。那么当定义的函数多了,就势必导致代码变成非常混乱和难读,这时候就需要学会多脚本链接了。
在一个名为script_1.sh的脚本写一个函数:

#! /bin/bash

function hello()
{
    name="$1"
    echo "hello, i am $name"
}

在一个名为script_2.sh的脚本调用hello函数,并且传入名字:

#! /bin/bash

source ./script_1.sh

hello "li hua"

当你在script_2.sh中执行source script_1.sh这句代码的时候,它会引入script_1.sh的文件的代码并执行它。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Halcon深度学习,语义分割,预处理和部署过程

halcon在深度学习中提供了7种学习方式和例子。其中最为常见的为语义分割&#xff0c;一般使用与在需要标注显示的缺陷检测项目中。几乎所有的2D缺陷检测都可以使用语义分割作为项目部署。 先上完整程序 预处理部分 *** 设置输入输出路径 *** *总路径 AllDir : E:/HALCONDeepin…

JavaScript的一个代码小挑战

题目 我们正在开发一个足球投注应用程序! 假设我们从一个网络服务获取了一场比赛的数据&#xff08;如下所示&#xff09;。在这个挑战中&#xff0c;我们将处理这些数据。这里是你的任务&#xff1a; const game {team1: Bayern Munich,team2: Borrussia Dortmund,players:…

适合家具集团的ERP软件有哪些?家具集团用什么ERP软件好

不同的家具企业有不同的经营策略和管理方式&#xff0c;同时在各个发展阶段遇会遇到各种新的问题&#xff0c;而这也对企业的信息化水平有着较高的要求。 另外&#xff0c;集团型家具企业通常涉及多仓库、多工厂、多平台、多业务模式等&#xff0c;而这些业务数据的实时和准确…

【趣味篇】Scratch之圣诞节跑酷

【作品展示】圣诞节跑酷 操作&#xff1a;点击小绿旗进入游戏主页面&#xff0c;不仅可以选择角色&#xff0c;而且选择好的角色还可以进行游戏闯关。

相对路径与绝对路径

1、相对路径与绝对路径 定义&#xff1a;要去的path是否和当前页面有联系 绝对&#xff1a; 1、http://www.baidu.com/a/b 2、/a/b 如果没有host则会直接取当前站点的host &#xff08;location.origion&#xff09; 相对&#xff1a; 1、当前是 http://www.baidu.com/a/b…

图像批量设计软件Retrobatch Pro mac中文版功能特色

Retrobatch Mac是一款灵活的批量图像处理工具。用户可以自由创建Workflow来实现相应的功能&#xff0c;这些Workflow能取代大量的重复劳动&#xff0c;提高生产力。Retrobatch Mac的一般操作是从左边栏拖动相应动作到工作区形成节点&#xff08;Nodes&#xff09;&#xff0c;节…

python+paddleocr 进行图像识别、找到文字在屏幕中的位置

目录 前言 1、安装paddleocr 2、安装PIL 3、安装numpy 4、 安装pyautogui 5、进行文本识别 6、识别结果 7、获取文字在图片/屏幕中的位置 8、pyautoguipaddleocr鼠标操作 9、完整代码 前言 最近在做自动化测试&#xff0c;因为是处理过的界面&#xff0c;所以使用pyw…

机器人制作开源方案 | 自主型收集餐盘机器人

作者&#xff1a;蔡佳怡、朱启会、郭晨杰、杨昊天、焦家辉 单位&#xff1a;西安外事学院 指导老师&#xff1a;杜喜昭、张燕 1. 产品说明 1.1 设计目的 对于如学校、工厂这种大型食堂&#xff0c;一般的收餐盘模式为用餐人用餐完毕后&#xff0c;把餐盘拿到最近的收餐盘点&…

社交泛娱乐出海,市场 赛道、投放 变现的最新干货分享

&#xff08;全网都在找的《社交泛娱乐出海作战地图》&#xff0c;点击获取&#x1f446;&#xff09; 11 月 29 日&#xff0c;融云、Flat Ads、Alibaba Cloud、TopOn 联合主办的“泛娱乐社交 App 出海新风口”主题沙龙在浙江杭州圆满收官。关注【融云全球互联网通信云】了解…

deepflow本地部署过程

本地服务器配置&#xff0c;32C&#xff0c;48G内存 整个过程需要配置k8s&#xff0c;安装helm, 安装grafana, 安装deepflow以及deepflow-ctl&#xff0c;以及部署demo 在采用sealos进行ALL-IN-ONE部署之前&#xff0c; grafana 先安装它 wget -q -O /usr/share/keyrings/gr…

自动化定时发送天气提醒邮件

&#x1f388; 博主&#xff1a;一只程序猿子 &#x1f388; 博客主页&#xff1a;一只程序猿子 博客主页 &#x1f388; 个人介绍&#xff1a;爱好(bushi)编程&#xff01; &#x1f388; 创作不易&#xff1a;如喜欢麻烦您点个&#x1f44d;或者点个⭐&#xff01; &#x1f…

智能安全芯片ACH512芯片描述及功能

ACH512 芯片是一款基于安全算法的高性能 SOC 芯片&#xff0c; 主要应用于 eMMC/SD/Nandflash 大容量存储设备、加密 U 盘、指纹识别等市场。 芯片采用 32 位内核&#xff0c;片内集成多种安全密码模块&#xff0c;包括SM1、 SM2、 SM3、 SM4、 SSF33 算法以及RSA/ECC、 ECDSA、…

4WRPH6C3B24L-2X/G24Z4/M伺服比例方向阀控制板

4WRPH6C3B12L-2X/G24Z4/M、4WRPH6C3B40P-2X/G24Z4/M、4WRPH6C3B40L-2X/G24Z4/M、4WRPH6C4B24L-2X/G24Z4/M、4WRPH6C4B40L-2X/G24Z4/M、4WRPH6C3B24L-2X/G24Z4/M、4WRPH10C4B100L-2X/G24Z4/M、4WRPH10C3B100L-2X/G24K0/M-750适合控制4WRPH系列比例伺服阀&#xff0c;用于安装在架…

rt-thread主线程启动流程

rt-thread主线程启动流程 1.启动分析2.源码分析 1.启动分析 基于&#xff1a;rt-thread-v5.0.1 先执行&#xff1a;汇编代码startup_stm32f429xx.s开始运行&#xff0c;主要调用SystemInit和 __main ; Reset handler Reset_Handler PROCEXPORT Reset_Handler …

功率信号源工作原理是什么

功率信号源是一种专门产生大功率信号的设备&#xff0c;主要用于驱动高功率负载&#xff0c;如电机、变频器等。其工作原理涉及信号生成、放大和输出三个关键步骤。 首先&#xff0c;信号生成。功率信号源通常会采用各种信号发生器来产生不同类型的信号波形。这些信号可以是正弦…

DenseNet分类网络改进(添加SPP)--亲测有效

最近&#xff0c;我在做多分类问题。在针对基模型的选择中&#xff0c;我使用了DenseNet作为基本模型。我在阅读论文时&#xff0c;遇到了一种改进方式&#xff1a; 如上图所示&#xff0c;在全连接层之前引入SPP模块&#xff1a; 代码如下&#xff1a; SPP模块代码&#x…

6 大 Android 照片恢复软件深度评测

当您发现令人难忘的照片在 Android 上被错误删除或丢失时&#xff0c;您可能会感到非常沮丧。然而&#xff0c;当您尝试安装一些恢复应用程序并希望将它们重新恢复时&#xff0c;其中许多应用程序无法再次检测到丢失的照片。 为了节省您逐一尝试此类应用程序的时间&#xff0c…

yum命令详解和使用

目录 一、yum介绍 常见的软件封包类型 RPM的含义 二、 yum命令格式 三、常用命令 3.1 yum清空缓存列表 3.2 yum显示信息 3.2 yum安装 3.3 yum删除 3.4 yum包的更新和升级 四、常用的国内 yum 源 一、yum介绍 Yum(全称为 Yellow dog Updater, Modified)&#xff0c;是…

西工大计算机学院计算机系统基础实验一(环境配置)

首先&#xff0c;不要焦虑&#xff0c;稳住心态慢慢来&#xff0c;一点一点做&#xff0c;跟着作者把基础打好&#xff0c;比什么都重要。作者曾经经历过这份痛苦&#xff0c;知道它有多么不好受。当初的作者高中之前甚至都没有自己的一台笔记本&#xff0c;上了大学以后学C语言…

unity旋转选中效果

代码和预制体 函数PlayAnim&#xff08;&#xff09;中的角度要根据按钮数量手动填好 using System; using DG.Tweening; using DG.Tweening.Core; using DG.Tweening.Plugins.Options; using UnityEngine;// Token: 0x0200001B RID: 27 public class BtnParentScript : Base…