linux学习:shell脚本

news2024/11/29 4:43:02

目录

要求

注意

变量

变量的定义和赋值

变量的引用

变量的种类

设置环境变量

特殊符号

引号

竖杠(管道)

和大于小于号(重定向)

字符串处理

测试语句

脚本语法

判断

循环

函数

trap


前提

要把 Shell 命令放到一个“脚本”当中,有一个前提:脚本的第一行必须写成类似这样 的格式: #!/bin/bash

这是给系统指定一款 Shell 解释器

注意

脚本文件缺省是没有执行权限的,要使得脚本可以执行必须给他添加权限

赋值号的两边没有空格!在 Shell 脚本中,任何时候要给变量赋值,赋值号两 边一定不能有空格

变量名也有类似于 C 语言那样的规定:只能包含英文字母和数字,且不能以数字开 头

变量

变量的定义和赋值

myname=”Michael Jackson”

变量的引用

使用变量时,需要在变量的前面加一个美元符号

变量的种类

  • A 普通的用户自定义变量,比如上面的 myname。
  • B 系统预定义好的环境变量,比如 PATH。
  • C 命令行变量,比如$#、$*等。

系统的环境变量可以通过如下命令来查看

  • env

每个环境变量都用大写字母表示,比如 PATH。每个 环境变量都有一个值,就是等号右边的字符串。根据环境变量的不同,它们各自的含义不同

设置环境变量

  • export PATH=dir/

PATH 环境变量的作用是保存系统中可执行程序或脚本的所在路径,因此它的值都是 一些以分号隔开的目录,我们经常的使用办法是:不改变其原有的值,而给它再增加一个我们自己需要设置的目录 dir/,因此更有用的命令可能是类似于以下这样的

  • export PATH=$PATH:dir/

而 Shell 脚本中的所谓命令行变量,指的是在脚本内部使用用户从命令行中传递进来的参数

  • ./example.sh abcd 1234

例如上面语句,脚本名叫 example.sh,咱们在执行他的时候顺便给了他两个参数,分别是 abcd 和 1234,要访问这两个参数以及相关的其他值,就必须使用命令行变量

  • $# :代表命令行参数个数,即 2
  • $* :代表所有的参数,即 abcd 1234
  • $@ :同上
  • $n :第 n 个参数,比如$1
  • $? :代表最后一个命令执行之后的返回值
  • $$ :代表当前 Shell 的进程号 PID

特殊符号

引号

引号有三种,他们是:双引号 “ ”、 单引号 ‘ ’、 反引号(抑音符) ` `

  • 双引号的作用是将一些“单词”括起来形成单个的“值”,还可以包括对变量的引用,还可以是一个命令
  • 被单引号所包含,那么 其内部的任何成分都将被视为普通的字符,而不是变量的引用或者命令
  • 反引号的作用就是在双引号中标识出命令
#!/bin/bash
var=calender
echo "var: date" # 直接打印出 var 和 date
echo "$var: `date`" # 打印出变量 var 的值,以及命令 date 的执行结果
echo '$var: `date`' # 打印出$var: `date`

竖杠(管道)

管道不仅可以连接两个命令,也可以连接多个命令

ls -l | wc
cat /etc/passwd | awk -F=/ '{print $1}' | wc

 这就将三个命令连接起来,每个命令的输出都作为下一个命令的输入,连接起来就能完成强 大的功能

和大于小于号(重定向)

每一个进程在刚开始运行的时候,系统都会为他们默认地打开了三个文件,他们分别是 标准输入、标准输出、标准出错

这三个标准文件对应两个硬件设备:标准输入是键盘,标准输出和标准出错是显示器(是 的,显示器设备被打开了两次,第一次打开为行缓冲类型的标准输出,第二次打开为不缓冲 类型的标准出错)。绝大多数的 Shell 命令,默认的输入输出都是这三个文件

当我们执行命令 ls 的时候,他会默认地将结果打印到显示器上,就是因为 ls 本 来就被设计为将结果往 1 号描述符(即标准输出,当执行成功的时候)或者 2 号描述符(即 标准出错,当执行失败的时候)。而当我们打开普通文件的时候,系统也会帮我们产生一系 列后续的数字(文件描述符)来表示这些文件,比如我们紧跟着打开了文件 a.txt 和 b.doc,

.假如需要将 ls 命令的成功的输出结果(本来会被默认地输送到 1 号文件描述符的信 息)重定向到 a.txt 文件中去

ls 1> a.txt

假如需要将 ls 命令的失败的输出结果(本来会被默认地输送到 2 号文件描述符的信息)重定向到 a.txt 文件中去

ls notexist 2> a.txt (notexist 是一个不存在的文件,所以 ls
命令执行会失败)

重定向标准输入也是类似的,比如直接执行 echo 命令,他将会默认地从标准输入(即 键盘)读取信息,然后打印出来。但是我们可以将标准输入重定向为 b.doc 文件:

echo 0< b.doc

 标准输入输出设备文件描述符要写成&0、&1 和&2。比 如要将一句话输出到标准出错设备中去

echo “hello world” 1>&2

字符串处理

计算一个字符串的字符个数

var="apple tree"
echo "${#var}"
10

删除一个字符串左边部分字符

path="/etc/rc0.d/K20openbsd-inetd"
level=${path#/etc/rc[0-9].d/[SK]}
echo $level
20openbsd-inetd

删除一个字符串右边部分字符

path="/etc/rc0.d/K20openbsd-inetd"
level=${path#/etc/rc[0-9].d/[SK]}
level=${level%%[a-zA-Z]*}
echo $level
20

注意

两个%%表示贪婪匹配,具体含义是:使用通配符[a-zA-Z]*从右向左“尽可能多地” 匹配字符(贪婪原则)。如果只写一个%,则无贪婪原则,那么[a-zA-Z]*将按照最少原则 匹配,即匹配 0 个字符(因为方括号星号*的含义是 0 个或多个字符)。这个道理对于删除 左边字符的井号#也是适用的:双井号##代表从左到右的贪婪匹配

测试语句

有一个叫 test 的命令,专门用来实现所谓的测试语句,测试语句可以测试很多不同的 情形

例子1

要判断一个文件 file 是否存在,而且可读,如果都满足的话就将其显示 在屏幕上,脚本可以写成这样

#!/bin/bash
if test -e file && test -r file
then
    cat file
fi
等价于
#!/bin/bash
if [ -e file ] && [ -r file ]
then
    cat file
fi

依靠 test 语句来决定是否要执行 cat 命令,这是脚本语言中最简单的条 件判断语句,根 C 语言的 if-else 结构很类似

  • 方括号的左右两边都必须有空格

脚本语法

判断

if [ -e file ] && [ -r file ]
then
    cat file
fi
  • 每一个 if 语句都有一个 fi(即倒过来写的 if)作为结束标记。
  • 分支结构中使用 then 作为起始语句。
  • 当且仅当 if 语句后面的语句执行结果为真(即为 0)时,then 以下的语句才会被 执行。当然,if 语句还可以跟 else 配对使用 
if [ -e file ] && [ -r file ]
then
    cat file # 如果文件存在且可读,则显示该文件内容
elif [ -e file ]
then
    chmod u+r file
    cat file # 如果文件存在但不可读,则加了读权限之后再显示其内容
else
    touch file # 如果文件不存在,则创建该空文件
fi
  •  elif 而不是 else if,其后也要跟 if 一样紧随 then 语句。如果是多路分支,可以使用 case 语句,这个类似于 C 语言中的 switch 语句。比如实现这么一个功能:要求用户输入 一个数字,判断如果输入的是 1,则输出 one,如果输入的是 2,则输出 two,输入其他数 字则输出 unkown,
read VAR # 从键盘接收一个用户输入
case $VAR in # 判断用户输入的值$VAR
    1) echo “one” # 如果$VAR 的值为 1,则显示 one
        ;; # 每个分支都必须以双分号作为结束(最后一个分支除外)
    2) echo “two” 6 
        ;;
    *) echo “unknown” # 星号*是 Shell 中的通配符,代表任意字符。
esac
  • 变量 VAR 的值实际上是字符串,因此上述代码中的 1) 也可写成 “1”)
  • 整个 case 结构必须 esac 作为结束

循环

实现打印 1 到 100 的功能

declare -i n=0 # 在定义变量 n 前面加上 declare -i 表示该变量为数值
while [ $n -le 100 ] # 如果 n 的值小于等于 100,则循
do # 循环体用 do 和 done 包含起来
    echo “$n” 
    n=$n+1 # 使 n 的值加 1
don
declare -i n=0
until [ $n -gt 100 ] # 如果 n 的值大于 100,则退出循环
do
    echo “$n” 
    n=$n+1
done

列出当前目录下每个普通文件所包含的行数

files=`ls` # 在当前目录下执行 ls,将所有的文件名保存在变量 files 中
for a in $files # 循环地将 files 里面的每个单词赋给 a,赋完则退出循环
do
    if [ -f $a ] # 如果文件$a 是一个普通文件,那么就计算他的行数
    then
        wc -l $a
    fi
done
  • for 循环中,in 后面接的是一个字符串,字符串里面包含几个单词循环体就执行几遍, 每执行一遍 a 的值都轮换地等于字符串里边的各个

函数

编写一个可以检测某用户是否在线的函数

check_user( ) # 定义一个函数 check_user( ),注意括号里面没有空格
{
    if [ $1 = "quit" ] # 若函数的第一个参数$1 为“quit”,则立即结束脚本
    then
        exit
    fi
    USER=`who | grep $1 | wc -l`
    if [ $USER -eq 0 ]
    then
        return 0 # 判断用户$1 是否在线,是则返回 1,否则返回 0
    else
        return 1
    fi
}
while true
do
    echo -n "input a user name:" 
    read USER
    check_user $USER # 调用 check_user,并传递参数$USER
    if [ $? -eq 1 ] # 判断 check_user 的返回值$?是否为 1
    then
        echo "[$USERNAME] online." 
    else
        echo "[$USERNAME] offline." 
    fi
done
  • 函数的定义中,括号里面不能写任何东西(第一行);函数必须定义在调用之前; 给函数传参的时候,传递的参数在函数的定义里用$n 来表示第 n 个参数。$?代表函数调用的返回值

trap

脚本中经常有信号处理的语句,最常见的情况是:当脚本收到某个信号的时候,需要处理一些清理工作,然后再退出,类似于 POSIX 编程中的信号处理。脚本中使用 trap 来达到这个目的。

trap “” INT
  • 当脚本收到信号 SIGINT 时,忽略该信号。在 Linux 中所支持的 信号可以使用命令 trap -l 来查看。信号名称的前缀要省略。trap 除了可以“忽略”信号

也可以“捕获”信号

trap do_something INT QUIT HUP
  • 当 脚 本 收 到 INT 、 QUIT 或 者 HUP 信 号 时 执 行 函 数 do_something

还可以指定脚本正常退出时的默认动作

trap on_exit EXIT
  • 当脚本正常退出时,执行函数 on_exit

当一 Shell 脚本 收到某一个信号的时候,我们需要该脚本立即终止,且要执行正常退出时的清理函数

trap on_exit EXIT
trap “:” INT HUP
  • 当脚本正常退出时执行函数 on_exit,当脚本收到信号 INT 或者 HUP 时执行空指令(此处冒号代表一个空指令,如果没有冒号,脚本将完全忽略该信 号,不做响应,不能立即退出),完了之后正常退出,此时触发 EXIT 从而执行函数 on_exit。

 

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

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

相关文章

《C语言深度解剖》(2):详解C语言分支语句和循环

&#x1f921;博客主页&#xff1a;醉竺 &#x1f970;本文专栏&#xff1a;《C语言深度解剖》 &#x1f63b;欢迎关注&#xff1a;感谢大家的点赞评论关注&#xff0c;祝您学有所成&#xff01; ✨✨&#x1f49c;&#x1f49b;想要学习更多数据结构与算法点击专栏链接查看&am…

使用tomcat里的API - servlet

一、创建一个新的Maven空项目 首次创建maven项目的时候&#xff0c;会自动从maven网站上下载一些依赖组件&#xff08;这个过程需要保证网络稳定&#xff0c;否则后续打包一些操作会出现一些问题&#xff09; ps:校园网可能会屏蔽一些网站&#xff0c;可能会导致maven的依赖…

深度学习500问——Chapter06: 循环神经网络(RNN)(4)

文章目录 6.14 常见的RNNs扩展和改进模型 6.14.1 Simple RNNs&#xff08;SRNs&#xff09; 6.14.2 Bidirectional RNNs 6.14.3 Deep RNNs 6.14.4 Echo State Networks&#xff08;ESNs&#xff09; 6.14.5 Gated Recurrent Unit Recurrent Neural Networks 6.14.6 Bidirection…

腾讯云4核8G服务器12M带宽646元1年零3个月,4C8G使用场景说明

腾讯云4核8G服务器多少钱&#xff1f;腾讯云4核8G轻量应用服务器12M带宽租用价格646元15个月&#xff0c;活动页面 txybk.com/go/txy 活动链接打开如下图所示&#xff1a; 腾讯云4核8G服务器优惠价格 这台4核8G服务器是轻量应用服务器&#xff0c;详细配置为&#xff1a;轻量4核…

idea 开发serlvet汽车租赁管理系统idea开发sqlserver数据库web结构计算机java编程layUI框架开发

一、源码特点 idea开发 java servlet 汽车租赁管理系统是一套完善的web设计系统sqlserver数据库 系统采用serlvetdaobean mvc 模式开发&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 java se…

git操作码云(gitee)创建仓库到上传到远程仓库

想必有的小伙伴在为上传到码云远程仓库而感到烦恼吧&#xff01;本篇为大家详细讲解实现过程&#xff0c;跟着我的步伐一步一步来。 我就当大家已经注册好了码云 一、在码云上需要的操作 接下来我们需要使用到 git 了 二、git 上的操作 到了咋们的git了&#xff0c;开整 首…

领鸡蛋游戏养鸡游戏淘宝客源码广告联盟

用户中心 用户信息&#xff1a;显示用户名、头像、鸡蛋数量、足迹等基本信息。我的足迹&#xff1a;展示用户的饲料获取记录明细&#xff0c;包括来源、数量和时间。我的好友&#xff1a;展示邀请的好友列表&#xff0c;支持好友间互动&#xff0c;如串门、偷取/赠送饲料&#…

Linux--APP打开的文件在内核中如何表示

当用户在程序中使用了glibc库提供的文件操作函数open&#xff08;&#xff09;、read&#xff08;&#xff09;等访问文件时&#xff0c;这些函数会调用相应的系统调用来实际执行文件操作&#xff0c;并返回一个整数即文件句柄&#xff0c;文件句柄实际上是对应的 struct file …

(React Hooks)前端八股文修炼Day9

一 对 React Hook 的理解&#xff0c;它的实现原理是什么 React Hooks是React 16.8版本中引入的一个特性&#xff0c;它允许你在不编写类组件的情况下&#xff0c;使用state以及其他的React特性。Hooks的出现主要是为了解决类组件的一些问题&#xff0c;如复杂组件难以理解、难…

网络安全意识也是基础防御中的关键一环

在当今数字化时代&#xff0c;网络安全已经成为企业和个人生活中不可或缺的一部分。网络攻击的不断演进和加剧使得保护个人隐私、商业机密和国家安全变得尤为重要。然而&#xff0c;网络安全并非仅仅是技术层面的问题&#xff0c;更是一个综合性的挑战&#xff0c;需要广泛的参…

区块链相关概念

区块链是什么&#xff0c;就算是做计算机技术开发的程序员&#xff0c;100个当中都没有几个能把这个概念理解明白&#xff0c;更不要说讲清楚了。那对于普通人来说&#xff0c;就更扯了。 除了“挖矿”表面意思似乎比较好理解外&#xff0c;其他的基础概念真TMD绕。 去中心化、…

堡垒机(安全运维,产品简述)

目录 跳板机与堡垒机 跳板机&#xff08;Jump Server&#xff09; 堡垒机&#xff08;Bastion Host&#xff09; 区别 堡垒机 功能 工作原理 类型 安全运维中的作用 jumpserver 简述 应用场景 技术特点 核心功能 主要组件 基础架构 应用架构 逻辑架构 优势 …

企业版ChatGPT用户激增至60万;百度文心一言推出个性化声音定制功能

&#x1f989; AI新闻 &#x1f680; 企业版ChatGPT用户激增至60万 摘要&#xff1a;OpenAI首席运营官Brad Lightcap在接受采访时透露&#xff0c;企业版ChatGPT的注册用户已超60万&#xff0c;相较2024年1月的15万用户&#xff0c;短短三个月内增长了300%。这一版本自2023年…

JavaScript逆向爬虫——使用Python模拟执行JavaScript

使用Python模拟执行JavaScript 通过一些调试&#xff0c;我们发现加密参数token是由encrypt方法产生的。如果里面的逻辑相对简单的话&#xff0c;那么我们可以用Python完全重写一遍。但是现实情况往往不是这样的&#xff0c;一般来说&#xff0c;一些加密相关的方法通常会引用…

2024年妈妈杯数学建模MathorCup数学建模思路B题思路解析+参考成品

1 赛题思路 (赛题出来以后第一时间在群内分享&#xff0c;点击下方群名片即可加群) 2 比赛日期和时间 报名截止时间&#xff1a;2024年4月11日&#xff08;周四&#xff09;12:00 比赛开始时间&#xff1a;2024年4月12日&#xff08;周五&#xff09;8:00 比赛结束时间&…

数据库相关知识总结

一、数据库三级模式 三个抽象层次&#xff1a; 1. 视图层&#xff1a;最高层次的抽象&#xff0c;描述整个数据库的某个部分的数据 2. 逻辑层&#xff1a;描述数据库中存储的数据以及这些数据存在的关联 3. 物理层&#xff1a;最低层次的抽象&#xff0c;描述数据在存储器中时如…

docker 部署 Epusdt - 独角数卡 dujiaoka 的 usdt 支付插件

部署 部署说明 部署之前必须注意的几点事项,该教程不一定适合所有用户: 本教程主要是使用 docker 部署,宝塔用户或宿主机直接安装的用户请直接参考官网教程.本教程是独立部署 epusdt,使用独立的mysql和redis,与dujiaoka项目分开. 在研究的过程中发现 epusdt 也需要用到 mys…

【Java】maven是什么?

先看一下基本概念: ①Maven 翻译为"专家"&#xff0c;"内行"是跨平台的项目管理工具。 主要服务于基于Java平台的项目构建&#xff0c;依赖管理和项目信息管理。 ②项目构建 项目构建过程包括【清理项目】→【编译项目】→【测试项目】→【生成测试报…

3D目标检测跟踪 | 基于kitti+waymo数据集的自动驾驶场景的3D目标检测+跟踪渲染可视化

项目应用场景 面向自动驾驶场景的 3D 目标检测目标跟踪&#xff0c;基于kittiwaymo数据集的自动驾驶场景的3D目标检测跟踪渲染可视化查看。 项目效果 项目细节 > 具体参见项目 README.md (1) Kitti detection 数据集结构 # For Kitti Detection Dataset └── k…

解决前端性能瓶颈:高效处理大量数据渲染与复杂交互的策略与优化方法

✨✨祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天开心&#xff01;✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; 目录 引言 一、分页加载数据 二、虚拟滚动 三、懒加载 四、数据缓存 五、减少重绘和回流 …