Shell 脚本学习

news2024/12/26 19:07:04

Shell学习

  1. Shell 脚本

    Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。

    Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。

    Ken Thompson 的 sh 是第一种 Unix Shell,Windows Explorer 是一个典型的图形界面 Shell。

  2. 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)

    这里我们学习的是 Bash,也就是 Bourne Again Shell,由于易用和免费 Bash 在日常工作中被广泛使用。同时,Bash 也是大多数 Linux 系统默认的 Shell。

  3. 编写第一个 Shell 脚本

    但是我们如何在 linux 下操作文件编写脚本呢?

    1. 打开文本编辑器(vi/vim命令可以创建文件)

      1. 这里就放张图简单介绍一下,东西太多了,这里就不细说了

      img

      img

      1. 首先我们打开或创建一个目录,并使用 vim filename 的方法打开或创建一个文件进行编辑

        oot@hcss-ecs-c2b8:/# cd /var
        root@hcss-ecs-c2b8:/var# 
        # 查看当前目录下的文件和文件夹
        root@hcss-ecs-c2b8:/var# ll
        total 56
        drwxr-xr-x 14 root root   4096 Sep 21 08:28 ./
        drwxr-xr-x 24 root root   4096 Sep 20 00:12 ../
        drwxr-xr-x  2 root root   4096 Sep 20 00:00 backups/
        drwxr-xr-x 16 root root   4096 Jul 22  2023 cache/
        drwxrwxrwt  2 root root   4096 Sep 20 06:25 crash/
        drwxr-xr-x 49 root root   4096 Sep 19 23:54 lib/
        drwxrwsr-x  2 root staff  4096 Apr 18  2022 local/
        lrwxrwxrwx  1 root root      9 Aug  9  2022 lock -> /run/lock/
        drwxrwxr-x 13 root syslog 4096 Sep 20 00:12 log/
        drwxrwsr-x  2 root mail   4096 Aug  9  2022 mail/
        drwxr-xr-x  2 root root   4096 Aug  9  2022 opt/
        lrwxrwxrwx  1 root root      4 Aug  9  2022 run -> /run/
        drwxr-xr-x  7 root root   4096 Jul 22  2023 snap/
        drwxr-xr-x  4 root root   4096 Aug  9  2022 spool/
        drwxr-xr-x  2 root root   4096 Sep 21 08:32 test/
        drwxrwxrwt  8 root root   4096 Sep 21 08:38 tmp/
        # 创建文件夹
        root@hcss-ecs-c2b8:/var# mkdir test
        mkdir: cannot create directory ‘test’: File exists
        root@hcss-ecs-c2b8:/var# cd /test
        -bash: cd: /test: No such file or directory
        # 进入文件夹并用vim命令创建文件并编辑
        root@hcss-ecs-c2b8:/var# cd test
        root@hcss-ecs-c2b8:/var/test# vim helloworld.sh
        
        # 编辑好使用:wq保存并退出
        #!/bin/bash
        echo "Hello world!"
        :wq
        
        root@hcss-ecs-c2b8:/var/test# ll
        total 16
        drwxr-xr-x  2 root root 4096 Sep 21 08:42 ./
        drwxr-xr-x 14 root root 4096 Sep 21 08:28 ../
        -rw-r--r--  1 root root   31 Sep 21 08:32 hello.sh
        -rw-r--r--  1 root root   32 Sep 21 08:42 helloworld.sh
        # 运行 shell 脚本
        root@hcss-ecs-c2b8:/var/test# ./helloworld.sh
        # 但是发现我们没有权限,为什么呢?
        -bash: ./helloworld.sh: Permission denied
        root@hcss-ecs-c2b8:/var/test# 
        

        不难看出我们创建的helloworld.sh文件他的权限信息为:-rw-r–r–,对于我们现在登录的root账号也就是对应的第二个到第四个"rw-"也就是仅仅只有读写的权限没有执行的权限,我们如何解决这个问题,

        这里放张图简单介绍一下权限信息

        363003_1227493859FdXT

      2. chmod 修改文件的权限

        chmod 777 filename 
        # 可以把九个二进制位置上有权限的值为1,那么三个一组可以用一个十进制整表示最大值为7即二进制的111
        
        # 修改文件权限
        # 修改前
        -rw-r--r--  1 root root   32 Sep 21 08:42 helloworld.sh
        root@hcss-ecs-c2b8:/var/test# chmod 777 helloworld.sh 
        # 修改后
        root@hcss-ecs-c2b8:/var/test# ls -al helloworld.sh 
        -rwxrwxrwx 1 root root 32 Sep 21 08:52 helloworld.sh
        # 现在运行我们编写的文件就没问题了,当然不用 chmod 777 只需要有执行权限也可以
        root@hcss-ecs-c2b8:/var/test# ./helloworld.sh
        Hello world!
        root@hcss-ecs-c2b8:/var/test# 
        # 100 对应---x------ 即 -001 000 000
        root@hcss-ecs-c2b8:/var/test# chmod 100 helloworld.sh 
        root@hcss-ecs-c2b8:/var/test# ls -al helloworld.sh 
        ---x------ 1 root root 32 Sep 21 08:52 helloworld.sh
        同样能执行成功
        root@hcss-ecs-c2b8:/var/test# ./helloworld.sh
        Hello world!
        root@hcss-ecs-c2b8:/var/test#
        

        到此我们的第一个 shell 脚本也就编写完毕了

  4. Shell 变量

    1. 变量的定义

在 Shell 编程中,变量是用于存储数据值的名称。

定义变量时,变量名不加美元符号($,PHP语言中变量需要),如:

your_name="runoob"

但是,有一点,变量名和等号之间不能有空格,这和我们之前的编程习惯有点区别

# 如果中间有空格,bash会把他等号以及之前的部分认为是一个命令,但这个命令也不存在就会报错
root@hcss-ecs-c2b8:/var/test# my_name= "zhengnan"
zhengnan: command not found

且需要遵守以下原则:

  • 只包含字母、数字和下划线: 变量名可以包含字母(大小写敏感)、数字和下划线 _,不能包含其他特殊字符。
  • 不能以数字开头: 变量名不能以数字开头,但可以包含数字。
  • 避免使用 Shell 关键字: 不要使用Shell的关键字(例如 if、then、else、fi、for、while 等)作为变量名,以免引起混淆。
  • 使用大写字母表示常量: 习惯上,常量的变量名通常使用大写字母,例如 PI=3.14
  • 避免使用特殊符号: 尽量避免在变量名中使用特殊符号,因为它们可能与 Shell 的语法产生冲突。
  • 避免使用空格: 变量名中不应该包含空格,因为空格通常用于分隔命令和参数。

有效的 Shell 变量名示例如下:

RUNOOB="www.runoob.com"
LD_LIBRARY_PATH="/bin/"
_var="123"
var2="abc"

无效的变量命名:

# 避免使用if作为变量名
if="some_value"
# 避免使用 $ 等特殊符号
variable_with_$=42
?var=123
user*name=runoob
# 避免空格
variable with space="value"

等号两侧避免使用空格:

# 正确的赋值
variable_name=value

# 有可能会导致错误
variable_name = value
  1. 如何使用变量

    普通变量

使用一个定义过的变量,只要在变量名前面加美元符号即可,如:

root@hcss-ecs-c2b8:/var/test# my_name=zhengNan
root@hcss-ecs-c2b8:/var/test# echo $my_name
zhengNan
root@hcss-ecs-c2b8:/var/test# my_name=zhengNan01
root@hcss-ecs-c2b8:/var/test# echo $my_name
zhengNan01

当我们给变量第N次赋值的时候都不用加美元符号’$’

变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,比如下面这种情况:

实例

for skill in Ada Coffe Action Java; do
echo "I am good at ${skill}Script"
done
如果不给skill变量加花括号,写成echo "I am good at $skillScript",解释器就会把$skillScript当成一个变量(其值为空),代码执行结果就不是我们期望的样子了。

推荐给所有变量加上花括号,这是个好的编程习惯。

只读变量

使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。

下面的例子尝试更改只读变量,结果报错:

root@hcss-ecs-c2b8:/var/test# only_read_variable="My birthday"
root@hcss-ecs-c2b8:/var/test# my_birthday="20010101"
root@hcss-ecs-c2b8:/var/test# readonly my_birthday
# 这里就算你赋值和原来一样也不行,只能读取,不能赋值
root@hcss-ecs-c2b8:/var/test# my_birthday="20010101"
-bash: my_birthday: readonly variable
root@hcss-ecs-c2b8:/var/test# my_birthday="200101011"
-bash: my_birthday: readonly variable

删除变量

使用 unset 命令可以删除变量。语法:

root@hcss-ecs-c2b8:/var/test# my_name=zhengnan
root@hcss-ecs-c2b8:/var/test# echo $my_name 
zhengnan
root@hcss-ecs-c2b8:/var/test# unset my_name 
root@hcss-ecs-c2b8:/var/test# echo $my_name 

root@hcss-ecs-c2b8:/var/test# unset my_birthday 
-bash: unset: my_birthday: cannot unset: readonly variable

需要注意的是,只读的变量无法删除会提示-bash: unset: my_birthday: cannot unset: readonly variable

变量类型

  1. 字符串变量

    在 Shell中,变量通常被视为字符串。

    你可以使用单引号 或双引号 " 来定义字符串,例如

    root@hcss-ecs-c2b8:/var/test# my_name="zhengnan"
    root@hcss-ecs-c2b8:/var/test# my_name='zhengnan'
    root@hcss-ecs-c2b8:/var/test# echo $my_name 
    zhengnan
    # 简单使用一下提取子字符串两参数开始提取的前一个位置和提取字符个数
    root@hcss-ecs-c2b8:/# my_name=zhengnan
    # 提取第1个位置开始后面五个字符
    root@hcss-ecs-c2b8:/# echo ${my_name:1:5}
    hengn
    root@hcss-ecs-c2b8:/# echo ${my_name:0:5}
    zheng
    # 查找子字符串
    root@hcss-ecs-c2b8:/# echo `expr index "$my_name" n`
    4
    root@hcss-ecs-c2b8:/# echo ${my_name:4:1}
    g
    root@hcss-ecs-c2b8:/# echo ${my_name:3:1}
    n
    # 这里用法是 expr index "变量" 目标字符串
    # 返回目标字符串里面第一个第一个出现在变量里的索引
    root@hcss-ecs-c2b8:/# echo `expr index "$my_name" z`
    1
    

    双引号的优点:

    • 双引号里可以有变量
    • 双引号里可以出现转义字符
  2. 整数变量

    在一些Shell中,你可以使用 declaretypeset 命令来声明整数变量。

    这样的变量只包含整数值,例如:

    root@hcss-ecs-c2b8:/var/test# declare -i my_age=23
    root@hcss-ecs-c2b8:/var/test# echo $my_age 
    23
    root@hcss-ecs-c2b8:/var/test# my_age="22"
    root@hcss-ecs-c2b8:/var/test# echo $my_age 
    22
    root@hcss-ecs-c2b8:/var/test# my_age="qwe"
    root@hcss-ecs-c2b8:/var/test# echo $my_age 
    0
    # 我们给my_age赋值一个不能转换的成整数的值,那么他就会变成默认值0
    root@hcss-ecs-c2b8:/var/test# my_age="zheng"
    root@hcss-ecs-c2b8:/var/test# echo $my_age 
    0
    # 我们重新赋值一个可以成功转化的值那么就能正常赋值
    root@hcss-ecs-c2b8:/var/test# my_age="123123"
    root@hcss-ecs-c2b8:/var/test# echo $my_age 
    123123
    

    这样的声明告诉 Shell 将 my_integer 视为整数,如果尝试将非整数值赋给它,Shell会尝试将其转换为整数,如果无法转换成整数那么他的值就会变成0

  3. Shell 数组

    bash支持一维数组(不支持多维数组),并且没有限定数组的大小。

    类似于 C 语言,数组元素的下标由 0 开始编号。获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于 0。

    # 在 Shell 中,用括号来表示数组,数组元素用"空格"符号分割开,我们之前学习的大部分数组都是逗号隔开。定义数组的一般形式为:
    # 数组名=(值1 值2 ... 值n)
    # 例如
    # array_name=(value0 value1 value2 value3)
    root@hcss-ecs-c2b8:/# language_array=(Java C C++ Erlang Ruby Rust) 
    # # 取得数组元素的个数
    root@hcss-ecs-c2b8:/# length=${#language_array[@]}
    root@hcss-ecs-c2b8:/# echo $length
    6
    root@hcss-ecs-c2b8:/# length=${#language_array[*]}
    root@hcss-ecs-c2b8:/# echo $length
    6
    # root@hcss-ecs-c2b8:/# length=${#language_array[n]} 获取索引为n的元素的长度
    root@hcss-ecs-c2b8:/# length=${#language_array[1]}
    root@hcss-ecs-c2b8:/# echo $length
    1
    root@hcss-ecs-c2b8:/# length=${#language_array[2]}
    root@hcss-ecs-c2b8:/# echo $length
    3
    root@hcss-ecs-c2b8:/# length=${#language_array[0]}
    root@hcss-ecs-c2b8:/# echo $length
    4
    root@hcss-ecs-c2b8:/# 
    
    
  4. Shell 注释

    # 开头的行就是注释,会被解释器忽略。

    通过每一行加一个 # 号设置多行注释,像这样:

    #--------------------------------------------
    # 这是一个注释
    # author:郑楠
    # site:www.jessamine.com
    # slogan:学的不仅是技术,更是梦想!
    #--------------------------------------------
    ##### 用户配置区 开始 #####
    #
    #
    # 这里可以添加脚本描述信息
    #
    #
    ##### 用户配置区 结束  #####
    

    多行注释
    使用 Here 文档

    多行注释还可以使用以下格式:

    :<<EOF
    注释内容...
    注释内容...
    注释内容...
    EOF
    

    以上例子中,: 是一个空命令,用于执行后面的 Here 文档,<<‘EOF’ 表示开启 Here 文档,COMMENT 是 Here 文档的标识符,在这两个标识符之间的内容都会被视为注释,不会被执行。
    EOF 也可以使用其他符号:

    实例

    : <<'COMMENT'
    这是注释的部分。
    可以有多行内容。
    COMMENT
    
    :<<'
    注释内容...
    注释内容...
    注释内容...
    '
    
    :<<!
    注释内容...
    注释内容...
    注释内容...
    !
    # 在控制台中的效果就是这样
    root@hcss-ecs-c2b8:/# :<<'COMMENT'
    > 23123
    > 
    > 321
    > 23
    > 123123
    > 
    > COMMENT
    root@hcss-ecs-c2b8:/# :<<1
    > 123123
    > 123
    > 1
    root@hcss-ecs-c2b8:/# 23
    123: command not found
    root@hcss-ecs-c2b8:/# :<<comment_tage
    > comment-context
    > comment-context-line2
    > comment_tag
    > 
    > comment_tage
    
    

    直接使用 : 号

    我们也可以使用了冒号 : 命令,并用单引号 ’ 将多行内容括起来。由于冒号是一个空命令,这些内容不会被执行。

    格式为:: + 空格 + 单引号。

    实例

    : '
    这是注释的部分。
    可以有多行内容。
    '
    

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

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

相关文章

安装了 cursor 之后,我写代码不用手了

最近新一代 AI 编程助手 cursor 爆火。 Cloudflare 副总裁家的 8 岁女儿在 45 分钟内用它搭起了一个聊天机器人。 这个女孩甚至不会编程&#xff0c;只是通过输入一些简单的 prompt 就完成了这样一个聊天机器人。 如果我们通过 RPA 或者智能体的方式&#xff0c;将语音直接转…

著名建筑物检测与识别系统源码分享

著名建筑物检测与识别检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Comp…

c++算法第二天

温馨提示&#xff1a;本篇文章适合刚开始练算法的小白&#xff0c;大佬若见勿嘲 题目 题目解析 遇到0写两遍&#xff0c;非0写一遍&#xff0c;其余非零数右移即可 编写原理 第一步找到最后一个被复写的数 先根据题目所给的例子找到最后一次要复写的数字 20240923_142843 第…

【AI学习】Lilian Weng:Extrinsic Hallucinations in LLMs(LLM 的外在幻觉)

来自OpenAI 的 Lilian Weng的《Extrinsic Hallucinations in LLMs》 Date: July 7, 2024 | Estimated Reading Time: 30 min | Author: Lilian Weng 文章链接&#xff1a;https://lilianweng.github.io/posts/2024-07-07-hallucination/ 大概看了一下&#xff0c;这篇文章的核…

重新拉取maven-jar包

问题&#xff1a;经常会出现这种情况&#xff1a;一个项目重新打包之后&#xff0c;在另外一个项目中无法引用。可以尝试一下解决方式 1&#xff1a;右上角重新拉取&#xff1a; 2&#xff1a;清理所有缓存&#xff1a;idea-file-invalidate Caches 3:设置拉取方式&#xff…

【论文速看】DL最新进展20240926-图像分割、图像修复、CNN

目录 【图像分割】【图像修复】【CNN】 【图像分割】 [2024] CAD: Memory Efficient Convolutional Adapter for Segment Anything 论文链接&#xff1a;https://arxiv.org/pdf/2409.15889 代码链接&#xff1a;https://github.com/Kyyle2114/Convolutional-Adapter-for-Segme…

Linux防火墙-什么是防火墙

作者介绍&#xff1a;简历上没有一个精通的运维工程师。希望大家多多关注作者&#xff0c;下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 什么是防火墙 我们想象一下把每台服务器当成一个小区&#xff0c;我们去访问另外一个小区的朋友&#xff0c;我们需要经过什…

什么是开放式耳机?具有什么特色?非常值得入手的蓝牙耳机推荐

开放式耳机是当下较为热门的一种耳机类型。它具有以下特点&#xff1a; 设计结构&#xff1a; 呈现开放式的构造&#xff0c;不会完全堵住耳道。如此一来&#xff0c;外界声音能够较容易地被使用者听到&#xff0c;在使用耳机时可以保持对周围环境的察觉。比如在户外&#xf…

每日一练:二叉搜索树中第K小的元素

230. 二叉搜索树中第 K 小的元素 - 力扣&#xff08;LeetCode&#xff09; 一、题目要求 给定一个二叉搜索树的根节点 root &#xff0c;和一个整数 k &#xff0c;请你设计一个算法查找其中第 k 小的元素&#xff08;从 1 开始计数&#xff09;。 示例 1&#xff1a; 输入&a…

配置anaconda环境变量的影响

配置anaconda环境变量的影响 配置虚拟机的过程&#xff1a;拉取一个配置为pytorch1.12.0-python3.7的docker镜像&#xff0c;创建虚拟机。创建好了之后验证了torch可以调用GPU。之后安装anaconda&#xff0c;并配置/root/anaconda的环境变量&#xff0c;之后创建虚拟环境wyq。…

性能优化与资源管理:优化Selenium脚本的执行效率,合理管理浏览器实例和系统资源

目录 引言 一、Selenium基础与常用方法 1.1 Selenium简介 1.2 Selenium基础用法 二、Selenium性能优化技巧 2.1 使用WebDriverWait实现显式等待 2.2 启用无头模式 2.3 设置合理的页面加载策略 2.4 禁用图片和JavaScript加载 2.5 优化元素定位 2.6 合理使用隐式等待和…

《经典图论算法》约翰逊算法(Johnson)

摘要&#xff1a; 1&#xff0c;约翰逊算法的介绍 2&#xff0c;约翰逊算法的实现步骤 3&#xff0c;约翰逊算法的准确性验证 4&#xff0c;约翰逊算法的代码实现 1&#xff0c;约翰逊算法的介绍 约翰逊算法(Johnson algorithm)是在稀疏图上求每对顶点之间最短路径的一种算法&a…

EchartJs报表展示

EchartJs报表展示 1、Echarts介绍 我们当前项目下的图形报表是使用echarts实现&#xff0c;所以接下来我们学习下echart的基本使用。 echarts Apache官网&#xff1a;https://echarts.apache.org/zh/index.html 点击所有示例&#xff0c;可快速学习echarts的基本使用&#x…

2024 大厂 Java 面试题汇总,作为 Java 程序员必须要掌握的技术栈

面试就是大家身边总是存在各种各样的可能,而自身又具备这样的能力,就忍不住想试一试&#xff0c;尤其是到了年关&#xff0c;是一个好的蓄势并且认真积累的阶段。当然面试套路众多&#xff0c;但对于技术面试来说&#xff0c;主要是考察一个人的技术能力和沟通能力。不同类型的…

一文了解智能无感知验证码

在数字化浪潮中&#xff0c;验证码作为守护信息安全的第一道关卡&#xff0c;其重要性日益凸显。它不仅用于识别真实用户与机器程序&#xff0c;更是防范网络攻击、保障数据安全的关键手段。本文将深入探讨验证码的定义、作用、分类&#xff0c;并重点介绍智能无感知验证码这一…

常用并发设计模式精讲

1. 优雅终止线程的设计模式 思考&#xff1a;在一个线程 T1 中如何优雅的终止线程 T2&#xff1f; 正确思路&#xff1a;两阶段终止模式 1.1 两阶段终止&#xff08;Two-phase Termination&#xff09;模式——优雅的终止线程 两阶段终止&#xff08;Two-phase Termination…

数据结构升华部分:排序与字符串匹配算法应用

数据结构入门学习&#xff08;全是干货&#xff09;——综合应用 习题选讲 - 排序与字符串匹配算法 习题选讲 - Insert or Merge 习题-IOM.1 插入排序的判断 题意理解 如何区分简单插入和非递归的归并排序 插入排序&#xff1a;前面有序&#xff0c;后面没有变化。归并排…

JUC高并发编程3:线程间通信

1 线程间通信 线程间通信的模型有两种&#xff1a;共享内存和消息传递&#xff0c;以下方式都是基本这两种模型来实现的。我们来基本一道面试常见的题目来分析 场景&#xff1a;两个线程&#xff0c;一个线程对当前数值加 1&#xff0c;另一个线程对当前数值减 1,要求用线程间…

【智能控制】第15章 智能优化算法,遗传算法

目录 15.1 遗传算法及其应用 15.1.1 遗传算法的基本原理 15.1.2 遗传算法的特点 15.1.3 遗传算法的应用领域 遗传算法的应用 15.1.4 遗传算法的设计 遗传算法的应用步骤 15.1.5 遗传算法求函数极大值 随着优化理论的发展&#xff0c;一些新的智能算法得到了迅速发…

深度学习:ResNet残差神经网络

目录 一、什么是ResNet残差神经网络 二、残差结构 三、18层残差网络 1.最初残差网络变体 2.图片示例 3.表格示例 四、批次归一化&#xff08;Batch Normalization&#xff09; 1.工作过程 2.主要作用 五、ResNet残差神经网络解决了传统神经网络什么问题 1.梯度消失和…