Shell编程基本介绍

news2024/12/24 22:09:15

文章目录

    • Shell简介
      • Shell环境
      • 第一个Shell脚本
      • Shell脚本的运行方法
    • 基础语法
      • Shell变量
        • 定义变量
        • 使用变量
        • 修改变量的值
        • 单引号和双引号的区别
        • 将命令的结果赋值给变量
        • 只读变量
        • 删除变量
      • Shell传递参数
      • 特殊字符处理参数说明
        • $* 与 $@ 区别
      • Shell字符串
        • 三种形式的区别
        • 获取字符串长度
        • Shell字符串拼接(连接、合并)
      • Shell字符串截取
        • 从指定位置开始截取
        • 从指定字符(子字符串)开始截取
        • 从指定字符(子字符串)开始截取
        • 字符串操作知识点汇总

Shell简介

Shell编程是一种使用Shell(命令行解释器)来编写脚本和程序的方法。Shell是用户与操作系统交互的接口,它允许用户通过命令行输入指令来执行程序、管理文件系统中的文件和目录等。Shell脚本是一种为Shell编写的脚本程序,用于自动化重复性任务、系统管理任务等。Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。

Shell环境

Shell 编程跟 JavaScript、php 编程一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了。
Linux 的 Shell 种类众多,常见的有:

  • Bourne Shell(/usr/bin/sh或/bin/sh)
  • Bourne Again Shell(/bin/bash)
  • C Shell(/usr/bin/csh)
  • K Shell(/usr/bin/ksh)
  • Shell for Root(/sbin/sh)

在一般情况下,人们并不区分 Bourne Shell 和 Bourne Again Shell,所以,像 #!/bin/sh,它同样也可以改为 #!/bin/bash。
#! 告诉系统其后路径所指定的程序即是解释此脚本文件的 Shell 程序

第一个Shell脚本

打开文本编辑器(可以使用 vi/vim 命令来创建文件),新建一个文件 test.sh,扩展名为 sh(sh代表shell),扩展名并不影响脚本执行,见名知意就好。 输入一些代码,第一行一般是这样:
在这里插入图片描述
代码解析
#! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪 一种 Shell。
echo 命令用于向窗口输出文本。

Shell脚本的运行方法

作为可执行程序,将上面的代码保存为 test.sh,并 cd 到相应目录:

在这里插入图片描述
注意,一定要写成 ./test.sh,而不是 test.sh,运行其它二进制的程序也一样,直接写 test.sh,linux 系统会去 PATH 里寻找有没有叫 test.sh 的,而只有 /bin, /sbin,/usr/bin,/usr/sbin 等在 PATH 里,你的当前目录通常不在 PATH 里,所以写成 test.sh 是会找不到命令的,要用 ./test.sh 告诉系统说,就在当前目录找
作为解释器参数,这种运行方式是,直接运行解释器,其参数就是 shell 脚本的文件名,如:
在这里插入图片描述

基础语法

Shell变量

变量是任何一种编程语言都必不可少的组成部分,变量用来存放各种数据。脚本语言在定义变量时通常不需要指明类型,直接赋值就可以,Shell 变量也遵循这个规则。
在 Bash shell 中,每一个变量的值都是字符串,无论你给变量赋值时有没有使用引号,值都会以字符串的形式存储。
这意味着,Bash shell 在默认情况下不会区分变量类型,即使你将整数和小数赋值给变量,它们也会被视为字符串,这一点和大部分的编程语言不同。例如在C语言或者 C++ 中,变量分为整数、小数、字符串、布尔等多种类型。当然,如果有必要,你也可以使用 Shell declare 关键字显式定义变量的类型,但在一般情况下没有这个需求,Shell 开发者在编写代码时自行注意值的类型即可。

定义变量

Shell 支持以下三种定义变量的方式:

  • variable=value
  • variable=‘value’
  • variable=“value”

注意,赋值号=的周围不能有空格,这可能和你熟悉的大部分编程语言都不一样。
Shell 变量的命名规范和大部分编程语言都一样:

  • 变量名由数字、字母、下划线组成;
  • 必须以字母或者下划线开头;
  • 不能使用 Shell 里的关键字(通过 help 命令可以查看保留关键字)。
使用变量

使用一个定义过的变量,只要在变量名前面加美元符号$即可,如:
在这里插入图片描述
变量名外面的花括号{ }是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,比如下面这种情况:
在这里插入图片描述
如果不给 skill 变量加花括号,写成echo “I am good at $Web”,解释器就会把 $skillWeb 当成一个变量(其值为空),代码执行结果就不是我们期望的样子了。
推荐给所有变量加上花括号{ },这是个良好的编程习惯。

修改变量的值

已定义的变量,可以被重新赋值,如:
在这里插入图片描述

第二次对变量赋值时不能在变量名加$ ,只有在使用变量时才能加$。

单引号和双引号的区别
单引号(')双引号(")
引用类型强引用弱引用
变量替换不替换替换
命令替换不执行执行(但需注意反引号与$()的区别)
特殊字符处理字面化部分特殊字符被解释和扩展
应用场景适用于需要原样输出字符串的场景适用于需要变量替换和简单命令执行的场景

在编写Shell脚本时,应根据具体需求选择使用单引号还是双引号来引用字符串。如果需要保持字符串的原始内容不变,包括其中的变量和命令,则应使用单引号。如果需要在字符串中嵌入变量或执行命令,并希望它们被替换或执行,则应使用双引号。

将命令的结果赋值给变量

Shell 也支持将命令的执行结果赋值给变量,常见的有以下两种方式:

  • variable=shell
  • variable=$(Shell)

第一种方式把命令用反引号 (位于 Esc 键的下方)包围起来,反引号和单引号非常相似,容易产生混淆,所以不推荐使用这种方式;第二种方式把命令用$()包围起来,区分更加明显,所以推荐使用这种方式。

只读变量

在Shell中,只读变量(read-only variable)是一种一旦被赋值后,其值就不能被改变的变量。这在你想要保护某些关键配置或数据不被意外修改时特别有用。在Bash(最常见的Shell之一)中,你可以使用readonly命令或declare -r命令来声明一个只读变量。

删除变量

使用 unset 命令可以删除变量。语法:
在这里插入图片描述
变量被删除后不能再次使用;unset 命令不能删除只读变量。

Shell传递参数

我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n。n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推……
例子:以下实例我们向脚本传递三个参数,并分别输出,其中 $0 为执行的文件名(包含文件路径):

#!/bin/sh
#接收文件外部传参
#超过十的数字用括号括起来
echo "接收第一个参数$0"
echo "接收第二个参数$1"
echo "接收第三个参数$2"
echo "接收第四个参数$3"
echo "接收第五个参数$4"
echo "接收第六个参数$5"

在这里插入图片描述

特殊字符处理参数说明

在这里插入图片描述
举例:

#!/bin/sh
echo "接收第二个参数$1"
echo "$# 个输出"
echo "输入的参数为$*"
echo "输入的参数为$@"

执行脚本,输出结果如下所示:
在这里插入图片描述

$* 与 $@ 区别

∗和@ 都是 Shell 脚本中的特殊变量,用于表示传递给函数或脚本的所有参数。它们之间的区别主要体现在如何处理这些参数上,特别是在被双引号包围时。
未被双引号包围时:

  • 在这种情况下,$* 和 $@ 几乎没有区别。它们都会将接收到的每个参数视为独立的,彼此之间以空格分隔。例如,如果传递给脚本的参数是 a b c,那么无论是 $* 还是 $@,在未被双引号包围时,它们都会被视为三个独立的参数。

被双引号包围时:

  • 当 $* 被双引号包围时,它会将所有的参数视为一个整体,即一个由 IFS分隔的单一字符串。这意味着,如果参数之间有空格,这些空格也会被包含在内,并且整个字符串被视为一个整体。
  • 而 $@ 即使被双引号包围,也会保持每个参数的独立性。每个参数都会被视为一个独立的字符串,彼此之间以空格分隔。

Shell字符串

字符串(String)就是一系列字符的组合。字符串是 Shell 编程中最常用的数据类型之一(除了数字和字符串,也没有其他类型了)
字符串可以由单引号’ '包围,也可以由双引号" "包围,也可以不用引号。它们之间是有区别的。

三种形式的区别
  1. 由单引号’ '包围的字符串:

    • 任何字符都会原样输出,在其中使用变量是无效的。
    • 字符串中不能出现单引号,即使对单引号进行转义也不行。
  2. 由双引号" "包围的字符串:

    • 如果其中包含了某个变量,那么该变量会被解析(得到该变量的值),而不是原样输出。
    • 字符串中可以出现双引号,只要它被转义了就行。
  3. 不被引号包围的字符串

    • 不被引号包围的字符串中出现变量时也会被解析,这一点和双引号" "包围的字符串一样。
    • 字符串中不能出现空格,否则空格后边的字符串会作为其他变量或者命令解析。
获取字符串长度

在 Shell 中获取字符串长度很简单,具体方法如下:
在这里插入图片描述
string_name 表示字符串名字。

Shell字符串拼接(连接、合并)

在Shell脚本中,字符串拼接(也称为连接或合并)是一项基本操作,用于将两个或多个字符串值组合成一个新的字符串值。Shell(如Bash)提供了多种方法来执行字符串拼接。
虽然双引号(")和单引号(')主要用于定义字符串,但它们并不直接用于拼接字符串。然而,你可以通过将多个字符串变量或字面量放在同一个双引号或单引号中来“模拟”拼接的效果,但这种方式更多是在定义字符串时包含变量或特殊字符。

# 使用双引号拼接字符串  
str1="Hello, "  
str2="World!"  
result="${str1}${str2}"  # 推荐的方式  
# 或者  
result="$str1$str2"      # 如果变量之间没有其他字符  
  
echo $result  # 输出: Hello, World!

printf命令提供了更灵活的字符串格式化选项,包括字符串拼接。

str1="Hello, "  
str2="World!"  
printf -v result "%s%s\n" "$str1" "$str2"  
  
echo $result  # 输出: Hello, World!

Shell字符串截取

Shell 截取字符串通常有两种方式:从指定位置开始截取和从指定字符(子字符串)开始截取。

从指定位置开始截取

  • 这种方式需要两个参数:除了指定起始位置,还需要截取长度,才能最终确定要截取的字符串。
  • 既然需要指定起始位置,那么就涉及到计数方向的问题,到底是从字符串左边开始计数,还是从字符串右边开始计数。答案是 Shell同时支持两种计数方式。

从指定字符(子字符串)开始截取

  • 这种截取方式无法指定字符串长度,只能从指定字符(子字符串)截取到字符串末尾。Shell可以截取指定字符(子字符串)右边的所有字符,也可以截取左边的所有字符。
从指定位置开始截取

从字符串左边开始计数,如果想从字符串的左边开始计数,那么截取字符串的具体格式如下:
在这里插入图片描述
其中,string 是要截取的字符串,start 是起始位置(从左边开始,从 0 开始计数),length 是要截取的长度(省略的话表示直到字符串的末尾)。
从右边开始计数,如果想从字符串的右边开始计数,那么截取字符串的具体格式如下:

从指定字符(子字符串)开始截取

使用 # 号截取右边字符,使用#号可以截取指定字符(或者子字符串)右边的所有字符,具体格式如下:
在这里插入图片描述
其中,string 表示要截取的字符,chars 是指定的字符(或者子字符串),*是通配符的一种,表示任意长度的字符串。*chars连起来使用的意思是:忽略左边的所有字符,直到遇见 chars(chars 不会被截取)。

从指定字符(子字符串)开始截取

以下写法也可以得到同样的结果:
在这里插入图片描述
如果不需要忽略 chars 左边的字符,那么也可以不写*,例如:
在这里插入图片描述
最后一个指定字符(子字符串)再匹配结束,那么可以使用##,具体格式为:
在这里插入图片描述

字符串操作知识点汇总

在这里插入图片描述

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

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

相关文章

ajax图书管理项目

bootstrap弹框 不离开当前页面,显示单独内容,让用户操作 功能:不离开当前页面,显示单独内容,供用户操作步骤: 1.引入bootstrap.css和bootstrap.js …

Java关键字及保留字总结

文章目录 Java关键字及保留字总结(按首字母字母顺序所排列)1.abstract2.boolean3.break4.byte5.case6.catch7.char8.class9.continue10.default11.do12.double13.else14.enum15.extends16.final17.finally18.float19.for20.if21.implements22.import23.i…

delphi 12 学习如何登陆网站下载文件

启动时等待验证码. 输入验证码后,等待处理数据 处理完成后,显示数据 实现原理:利用已有的账号和密码登录后产生的cookie,向服务器请求数据.返回的数据是JSON格式,后期需要自己整理. 注意,请在程序中使用同一个TnetHttpClient控件来完成.因为里面保存了cookie信息 需要了解的知…

C#编写软件发布公告1——客户端

前言 软件或者生活中有时需要将信息同步至电子公告板上,利用C#可以快速实现这一目的,这里以软件公告场景设计,主要是将软件的版本号等相关信息同步至服务器,同步成功后,任务需要查找的人员只要有Web浏览器就可以快速查…

用前所未有的方式体验我们的现代 API 文档

增强您的 API 文档 对于开发人员 为内部和外部消费者创建从 API 定义文件自动生成的精美 API 文档。 只需 4 个简单步骤即可编写 API 文档 API 采用的成功取决于 API 文档的质量。 Baklib 从您的 API 定义文件创建漂亮的(完全可定制的)API 文档。帮助…

4个自定义倒计时

<!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><title>4个自定义倒计时</title><style>* {margin: 0;padding: 0;box-sizing: border-box;user-select: none;body {background: #0b1b2c;}}hea…

DedeCms 织梦系统 漏洞 上传webshell复现 四种方法 超详细

DedeCMS是织梦团队开发PHP 网站管理系统&#xff0c;它以简单、易用、高效为特色&#xff0c;组建出各种各样各具特色的网站&#xff0c;如地方门户、行业门户、政府及企事业站点等。 目录 方法一 &#xff1a;通过⽂件管理器上传WebShell 方法二&#xff1a;修改模板⽂件拿…

邻接矩阵实现图的存储

目录 一. 前言 二. 用邻接矩阵来实现图的存储 一. 前言 1. 图的定义 所谓图就是包含顶点和边的集合&#xff0c;是一种多对多的关系。用符号表示为&#xff1a;G(V,E)。其中&#xff0c;V代表顶点&#xff08;数据元素&#xff09;的有穷非空集合&#xff0c;E代表边的有穷集…

AI4-PPOCRLabel安装

推荐环境&#xff1a; - PaddlePaddle > 2.1.2 - Python 3.7 - CUDA10.1 / CUDA10.2 - CUDNN 7.6 1、安装Anaconda 说明&#xff1a;使用paddlepaddle需要先安装python环境&#xff0c;这里我们选择python集成环境Anaconda工具包 Anaconda是1个常用的python包管理程序 安装完…

虚拟机连接xshell的三种方式

第一 桥接 改为输入 systemctl restart network 关闭自启动防火墙 systemctl stop firewalld systemctl disable firewalld 查看本机网络信息 ifconfig 连接xshell 第二 nat 第三 仅主机

探索 Electron:打造深度书籍挖掘机的搜索体验

Electron是一个开源的桌面应用程序开发框架&#xff0c;它允许开发者使用Web技术&#xff08;如 HTML、CSS 和 JavaScript&#xff09;构建跨平台的桌面应用程序&#xff0c;它的出现极大地简化了桌面应用程序的开发流程&#xff0c;让更多的开发者能够利用已有的 Web 开发技能…

react-native从入门到实战系列教程-React Native Elements

react-native的ui框架内网真的是屈指可数&#xff0c;能用的成熟的几乎找不到。不像web端的繁荣景象&#xff0c;可以用荒凉来形容不为过。 京东的nutui说也支持react-native,官网及其简陋。尝试了未成功运行&#xff0c;可能是项目类型不同&#xff0c;对比其他类型的ui库都分…

centos安装es、kibana、ik

这里es使用的是7.10.2版本的es&#xff0c;物料包下载地址如下 #注意安装的插件需和es版本保持一致 #es https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.10.2-linux-x86_64.tar.gz #kibana https://artifacts.elastic.co/downloads/kibana/kibana-7.10…

phpMyAdmin之CMS靶场

方法一&#xff1a;通过日志文件拿webshell 常用的语句如下&#xff1a; show global variables like %general%; set global general_logon; set global general_log_file D:/phpStudy_pro/WWW/muma.php; show global variables like %general%; select <?php eval($_…

广西南宁高校大学智能制造实验室数字孪生可视化系统平台建设项目验收

南宁高校大学智能制造实验室&#xff0c;作为该地区乃至全国智能制造领域的重要研究和教学基地&#xff0c;一直致力于探索和创新智能制造技术。近日&#xff0c;该实验室的数字孪生可视化系统平台建设项目成功通过了验收&#xff0c;标志着其在数字孪生技术领域取得了重大突破…

c语言排序(2)

前言 在上一篇文章&#xff0c;我们学习了插入排序&#xff0c;选择排序以及交换排序中的冒泡排序&#xff0c;接下来我们继续学习交换排序、归并排序以及非比较排序。 1. 快速排序 快速排序是交换排序的一种&#xff0c;它的基本思想&#xff1a;任取待排序序列中的某元素作…

z3基础学习

z3基础学习 ​ z3是一个微软出品的开源约束求解器&#xff0c;能够解决很多种情况下的给定部分约束条件寻求一组满足条件的解的问题。 安装&#xff1a;pip install z3-solver 1. 简单使用 from z3 import * x Int(x) #创建名为x的int类型变量 y Int(y) solve(x y10,2*x…

【Verilog-CBB】开发与验证(1)——开个头

在Verilog代码设计的过程中&#xff0c;经常会涉及到一些常用组件的应用&#xff0c;比如仲裁器、打拍器、RS双向打拍器等。这些组件如果重复开发就会降低效率。这些常用的组件业内称为CBB&#xff08;Common Building Block&#xff09;。本专栏旨在开发一些好用易用的CBB&…

前端拥抱AI:LangChain.js 入门遇山开路之PromptTemplate

PromptTemplate是什么 PromptTemplate是一个可重复使用的模板&#xff0c;用于生成引导模型生成特定输出的文本。与Prompt的区别: PromptTemplate相对于普通Prompt的优势&#xff0c;即其灵活性和可定制性。 简单了解PromptTemplate后&#xff0c;咱们就来聊聊LangChain里的P…

Linux配置FTP服务

一、FTP服务基本信息 FTP服务器&#xff1a;一种应用广泛且古老的互联网文件传输协议&#xff0c;主要用于文件的双向传输。 默认端口号&#xff1a;21 全称&#xff1a;vsftpd 二、搭建FTP服务 1.关闭防火墙和selinux&#xff08;若linux系统没有这两种功能&#xff0c;跳…