Shell 脚本学习

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!"
        :wqroot@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.xdnf.cn/news/147360.html

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

相关文章

xxl-job使用总结

xxl-job从入门到入土 xxl-job介绍 xxl-job是一个分布式任务调度平台&#xff0c;其核心设计目标是开发迅速、学习简单、轻量级、易扩展。xxl-job支持调度中心集群和执行器集群。 xxl-job开源项目 xxl-job使用 xxl-job整合SpringBoot 引入xxl-job的依赖 <dependency>…

ArcGIS核密度分析(栅格处理范围与掩膜分析)

多时候我们在进行栅格分析的时候&#xff0c;处理的结果不能完全覆盖我们需要的范围。 比如&#xff0c;我们对点数据进行密度分析、栅格插值等。比如下图 为什么会如此呢&#xff1f; 那是因为在做这个密度分析或者栅格插值的时候&#xff0c;默认是以点的四至范围来生成的&am…

LeetCode 热题 100 回顾9

干货分享&#xff0c;感谢您的阅读&#xff01;原文见&#xff1a;LeetCode 热题 100 回顾_力code热题100-CSDN博客 一、哈希部分 1.两数之和 &#xff08;简单&#xff09; 题目描述 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标…

算法之逻辑斯蒂回归(Logistic regression)

简介&#xff1a;个人学习分享&#xff0c;如有错误&#xff0c;欢迎批评指正。 逻辑斯蒂回归&#xff08;Logistic Regression&#xff09;是统计学中一种广泛应用于二分类问题的算法。它的主要目标是预测二分类问题中的事件发生的概率。尽管名字里有“回归”&#xff0c;但逻…

2024已然过半,AI技术卷到哪儿了?

可以说&#xff0c;科技的发展真的是日新月异&#xff0c;2024年年初&#xff0c;大模型Sora的出现&#xff0c;改变了短视频行业的演变方向&#xff0c;使得AI技术不再只是停留在文生文&#xff0c;文生图阶段&#xff0c;而是发展到了文生视频领域。2024年5月&#xff0c;回忆…

Java笔试面试题AI答之设计模式(5)

文章目录 21. 简述Java什么是适配器模式 ?适配器模式的主要组成部分包括&#xff1a;适配器模式的实现方式主要有两种&#xff1a;适配器模式的优点&#xff1a;适配器模式的缺点&#xff1a;示例说明&#xff1a; 22. 请用Java代码实现适配器模式的案例 &#xff1f; 21. 简述…

OpenCL 学习(2)---- OpenCL Platform 和 Device

目录 OpenCL PlatformOpenCL Device参考代码 OpenCL Platform opencl 支持的 Platform 可以使用 clGetPlatformIDs 函数查询&#xff0c;函数原型如下&#xff1a; clGetPlatformIDs(cl_uint /* num_entries */,cl_platform_id * /* platforms */,cl_uint * …

深度之眼(三十)——pytorch(一)--深入浅出pytorch(附安装流程)

文章目录 一、前言一、pytoch二、六个部分三、如何学习四、学习路径&#xff08;重要)五、安装pytorch5.1 坑15.2 坑2 一、前言 我看了下目录 第一章和第二章都是本科学的数字图像处理。 也就是这一专栏&#xff1a;数字图像实验。 所以就不准备学习前两章了&#xff0c;直接…

神奇的可变模板参数的应用(C++标准库双向链表 list 中的emplace函数实现)

我们先来看一个可以构造任意对象的函数&#xff1a; /// <summary> /// 可以构造任意对象的函数 /// </summary> /// <typeparam name"MyClass">要转换对象的类型</typeparam> /// <typeparam name"...MyClassConstructorParameterT…

新手上路:在Windows CPU上安装Anaconda和PyCharm

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一. 确认自己是CPU为什么选择CPU教程&#xff1f;GPU与CPU的区别如何判断自己是CPU 二. Anaconda 安装包 和 Pycharm 安装包步骤1&#xff1a;下载Anaconda步骤2&am…

摆脱困境并在iPhone手机上取回删除照片的所有解决方案

您是否无意中从 iPhone 中删除了照片&#xff1f;您&#xff0c;无需惊慌&#xff0c;因为您可以使用以下方法恢复所有照片。 如果您长时间使用 iPhone&#xff0c;您应该知道 iOS 提供了许多 Android 不提供的备份功能。例如&#xff0c;您的所有照片都会自动备份到 iCloud 存…

5分钟内理解 .prototype 链 | 2024

在JavaScript的世界里,原型(prototype)系统是一个常被讨论但不易掌握的概念。作为JavaScript继承模型的基石,理解原型对于构建大型应用或进行对象操作至关重要。让我们一起探索这个迷人的话题,揭开原型系统的神秘面纱。 什么是原型? 在JavaScript中,每个对象都有一个内部属性[…

常见中间件漏洞(Jboss)靶场

1.CVE-2015-7501 开启环境查看端口 http://192.168.10.194:8080/ invoker/JMXInvokerServlet 说明接⼝开放&#xff0c;此接⼝存在反序列化漏洞 下载 ysoserial ⼯具进⾏漏洞利⽤ https://github.com/frohoff/ysoserial 将反弹shell进⾏base64编码 bash -i >& /dev/…

C++ Qt 之 QPushButton 好看的样式效果实践

文章目录 1.前序2.效果演示3.代码如下 1.前序 启发于 edge 更新 web 页面&#xff0c;觉得人家做的体验挺好 决定在Qt实现&#xff0c;方便以后使用 2.效果演示 特性介绍&#xff1a; 默认蓝色鼠标移入 渐变色&#xff0c;鼠标变为小手鼠标移出 恢复蓝色&#xff0c;鼠标恢…

【学习笔记】 AD24中元器件重叠系统不报错的解决方案(消除报错)

【学习笔记】 AD24中PCB设计元器件重叠后系统不报错的解决方案&#xff08;如何主动屏蔽报错&#xff09; 一、Component Clearance未开启使能的解决方案二、最小水平间距设置错误的解决方案三、未开启设计规则检查的解决方案四、设计规则检查中 “在线”和“批量”的含义五、为…

前端——JavaScript练习 做一个todoList

用前端制作一个todoList的表格&#xff0c;实现更新、删除、修改等功能。 涉及几个知识点&#xff1a; 设置最小高度&#xff08;宽度&#xff09;&#xff1a; .container{min-width: 350px;/* 最小宽度 最小不会小于210px */ } 去掉外轮廓 outline: none; 去除字…

寄存器与内存

第三课&#xff1a;寄存器与内存、中央处理器&#xff08;CPU&#xff09;、指令和程序及高级 CPU 设计-CSDN博客 锁存器 引入 ABO0&#xff08;开始状态&#xff09;001&#xff08;将A置1&#xff09;110&#xff08;将A置0&#xff09;11 无论怎么做&#xff0c;都没法从1变…

深度学习(一):神经网络入门

文章目录 一、神经网络1.1神经元结构1.2单层神经网络&#xff1a;单层感知机1.3两层神经网络&#xff1a;多层感知机1.4多层神经网络 二、全连接神经网络2.1基本结构2.2激活函数、前向传播、反向传播、损失函数2.2.1激活函数的意义2.2.2前向传播2.2.3损失函数、反向传播2.2.4梯…

uniapp小程序持续获取用户位置信息,后台位置获取

做一个小程序持续获取用户位置信息的功能&#xff0c;即使小程序切换到后台也能继续获取&#xff0c;getLocation这个api只有小程序在前台才能获取位置&#xff0c;所以不用这个 先申请一个腾讯地图key 在uniapp项目配置源码视图里加上这个代码 先获取权限&#xff0c;再开启…

NtripShare测量机器人自动化监测系统测站更换仪器后重新设站

NtripShare测量机器人自动化监测系统投入商业运营已经很久了&#xff0c;在MosBox与自动优化网平差技术的加持下&#xff0c;精度并不让人担心&#xff0c;最近基于客户需求处理了两个比较大的问题。 1、增加对反射片和免棱镜的支持。 2、进一步优化测站更换仪器或重新整平后重…