命令行之巅:Linux Shell编程的至高艺术(上)

news2025/2/4 5:59:53

文章一览

  • 前言
  • 一、shell概述
    • 1.1 shell的特点和类型
      • 1.1.1 **shell的特点:**
      • 1.1.2 常用shell类型
    • 1.2 shell脚本的建立和执行
      • 1.2.1 建立shell脚本
      • 1.2.2 执行shell脚本的方式
      • 1.2.3 shell程序实例
  • 二、shell变量与算数运算
    • 2.1 简单shell变量
      • 2.1.1 简单变量定义和赋值
      • 2.1.2 引用变量值
      • 2.1.3 删除变量
    • 2.2 数组
    • 2.3 位置参数
      • 2.3.1 位置参数
      • 2.3.2 shift命令
      • 2.3.3 用set命令为位置参数赋值
    • 2.4 预先定义的特殊变量
    • 2.5 环境变量
    • 2.6 运算
      • 2.6.1 let命令
      • 2.6.2 运算符及其优先级和结合性
      • 2.6.3 关系运算符
      • 2.6.4 算数运算符
      • 2.6.5 布尔运算符
      • 2.6.6 逻辑运算符
      • 2.6.7 字符串运算符
        • 获取字符串长度
      • 2.6.8 文件测试运算符

前言

在浩瀚的数字世界中,Linux以其坚不可摧的内核和无限的可能性,成为了开发者和系统管理员的挚爱。而在这个由代码编织的宇宙里,Shell程序就像是一把钥匙,能够解锁Linux操作系统的无尽潜能。今天,我们将一同探索Linux中的shell程序设计,这是一段既充满挑战又令人兴奋的旅程。

Shell是系统的用户界面,提供了用户与内核进行交互操作的一种接口。它接收用户输入的命令并把它送入内核去执行。

实际上Shell是一个命令解释器, 它解释由用户输入的命令并且把它们送到内核。不仅如此,Shell有自己的编程语言用于对命令的编辑,它允许用户编写由shell命令组成的程序。 Shell编程语言具有普通编程语言的很多特点,比如它也有循环结构和分支控制结构等,用这种编程语言编写的Shell程序与其他应用程序具有同样的效果。

本篇文章将介绍什么是shell以及shell的中的变量运算

一、shell概述

1.1 shell的特点和类型

1.1.1 shell的特点:

  • 组合新命令很简单;
  • 提供了文件名扩展字符
  • 可以直接使用shell的内置命令 ;
  • 允许灵活地使用数据流 ;
  • 结构化的程序模块 ;
  • 提供了在后台(&)执行命令
  • 提供了可配置的环境;
  • 提供了一个高级的命令语言 。

1.1.2 常用shell类型

  • Bourne shell(简称sh)
  • C—shell(简称csh)
  • Korn shell(简称ksh)
  • Bourne Again shell(简称bash)

1.2 shell脚本的建立和执行

1.2.1 建立shell脚本

建立shell脚本的步骤同建立普通文本文件的方式相同,如:

vi  ex1

1.2.2 执行shell脚本的方式

执行shell脚本的常用方式基本上有两种:

(1)以脚本名作为参数。其一般形式是:

​ $ bash 脚本名 [参数]

​ $ · 脚本名 [参数]

(2)将shell脚本的权限设置为可执行,然后在提示符下直接执行它。

​ $ chmod a+x ex2

​ $ PATH=$PATH:•

​ $ ex2 或者 $ •/ex2

1.2.3 shell程序实例

注意,一定要写成 ./test.sh,而不是 test.sh,运行其它二进制的程序也一样,直接写 test.sh,linux 系统会去 PATH 里寻找有没有叫 test.sh 的,而只有 /bin, /sbin, /usr/bin,/usr/sbin 等在 PATH 里,我们的当前目录通常不在 PATH 里,所以写成 test.sh 是会找不到命令的,要使用 ./test.sh 告诉系统在当前目录寻找。

二、shell变量与算数运算

2.1 简单shell变量

2.1.1 简单变量定义和赋值

变量名=字符串  

注意在赋值号“=”的两边没有空格 , 例如:

myfile=/home/cieeqc/ff/m1.c

变量名以字母或下线符打头的字母、数字和下线符序列,大小写字母意义不同。

注意,变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样。同时,变量名的命名须遵循如下规则:

命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。

中间不能有空格,可以使用下划线(_)。

不能使用标点符号。

不能使用bash里的关键字(可用help命令查看保留关键字)。

2.1.2 引用变量值

  • 在程序中引用变量值时,要在变量名前面加上一个“$”符号。
$ dir=/home/ciee/ff
$ echo  $dir
/home/ciee/ff     (显示变量dir的值)
$ echo  dir
dir            (显示一般的字符串常量dir)
$ echo $Dir
(显示一个空串)
$ 
  • 如果在赋给变量的值中含有空格、制表符或换行符,那么,就应该用双引号把这个字符串括起来。

应注意的情况

  1. $ dir=/home/ci
    $ cat  ${dir}ee/file1.c      #将把文件/home/ciee/m1.c显示出来 
    3 而   
    $ cat  $dirqc/file1.c         #系统会给出错误信息
    
  2. $ dir1=/home/ciee/ff/prog
    $ ls  $dir1
    $ cat  $dir1/exam.c
    
  • 变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,比如下面这种情况:
for skill in Ada Coffe Action Java; do
    echo "I am good at ${skill}Script"
done

如果不给skill变量加花括号,写成echo “I am good at $skillScript”,解释器就会把$skillScript当成一个变量(其值为空),代码执行结果就不是我们期望的样子了。

2.1.3 删除变量

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

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

变量被删除后不能再次使用。unset 命令不能删除只读变量

#!/bin/sh  
myUrl="http://www.ipieuvre.com"  
unset myUrl  
echo $myUrl 

以上实例执行后将没有任何输出。

2.2 数组

Bash Shell 只支持一维数组(不支持多维数组),初始化时不需要定义数组大小(与 PHP 类似)。

与大部分编程语言类似,数组元素的下标由0开始。

  • 对数组元素赋值的一般形式是: 数组名[下标]=值
$ city[0]=Beijing
$ city[1]=Shanghai
$ city[2]=Tianjin
  • 用declare命令显式声明一个数组,一般形式是:declare -a

  • 数组名读取数组元素值的一般格式是:${数组名[下标]} 例如:$ echo ${city[0]}

  • 数组初始化的一般形式是: 数组名=(值1 值2 … 值n) $ A=(this is an example of shell script)

$ A=(this is an example of shell script)
$ echo  ${A[0]}  ${A[2]}  ${A[3]}  ${A[6]}
this an example script
$ echo  ${A[8]}
(A[8]超出了数组A的范围,所以它的值是空串。)
$ ▌

使用*或@作为下标,则表示数组中所有元素

2.3 位置参数

2.3.1 位置参数

exam   m1   m2  m3  m4
   $0     $1    $2   $3   $4   $5    $6   $7   $8    $6   ${10}  ${11}

这种变量不能用赋值语句直接赋值,只能通过命令行上对应位置的实参传值。

$0始终表示命令名或shell脚本名。

2.3.2 shift命令

用shift命令移动位置参数

  1. $0:脚本的名称。
  2. $1$9:传递给脚本的第一个到第九个参数。
  3. $#:传递给脚本的参数总数。
  4. $*$@:所有的位置参数,区别在于,$* 会将所有参数视为一个整体,而 $@ 会将每个参数视为独立的元素,这在循环遍历参数时非常有用。

示例:

假设你有一个名为 script.sh 的脚本,并且你通过以下命令调用它:

shell

./script.sh arg1 arg2 arg3

在这个例子中,arg1arg2arg3 是传递给脚本的位置参数。在脚本内部,你可以这样访问它们:

  • $1 的值是 arg1
  • $2 的值是 arg2
  • $3 的值是 arg3
  • $# 的值是 3,因为有3个参数。
  • $* 的值是 arg1 arg2 arg3,所有参数作为一个整体。
  • $@ 的值是 arg1 arg2 arg3,每个参数作为独立的元素。

以下是如何在脚本中使用这些位置参数的一个简单示例:

#!/bin/bash

# 打印脚本名称
echo "Script name: $0"

# 循环遍历所有参数
echo "Looping through all arguments:"
for arg in "$@"; do
    echo "Argument: $arg"
done

# 打印参数总数
echo "Total number of arguments: $#"

# 打印所有参数作为一个整体
echo "All arguments as a whole: $*"

2.3.3 用set命令为位置参数赋值

$ cat  exam4
#!/bin/bash
# exam4: shell  script  to  combine  files  and  count  lines
# using  command  set  to  set  positional  parameters
set  file1.c  file2.c
cat  $1  $2  $3 | wc  -l
# end
$ exam4
????
$ ▌

2.4 预先定义的特殊变量

⑴$#——除脚本名外,命令行上参数的个数。

⑵$?——上一条前台命令执行后的返回值(也称“退出码”等)。 0表示没有错误,其他任何值表示有错误。

⑶$$——当前进程的进程号(ID号)。

⑷$!——上一个后台命令对应的进程号。

⑸$*——表示在命令行上实际给出的所有实参。如输入下面的命令行:

exam3  A  B  C  D  E  F  G  H  I  J  K
# 则$* 就是:A  B  C  D  E  F  G  H  I  J  K
#而“$*”就等价于:
#"$1  $2  $3……",即:" A  B  C  D  E  F  G  H  I  J  K"。 

⑹$@——它与$基本功能相同。但“$@”与“$”不同。

“$@”就等价于: “$1” “$2”……,在上面情况下,就是"A" “B” “C”……“K”。

(7) $- 显示shell的当前选项,与set命令功能相同

2.5 环境变量

(1)HOME:用户主目录的全路径名。如/home/myname

(2)LOGNAME:即用户注册名

(3)PWD:当前工作目录的路径。

(4)PATH:shell查找命令的路径(目录)列表,各个目录用冒号(:)隔开。

#用户可以设置它:   
$ PATH=$PATH:$PWD

(5)PS1:shell的主提示符。 \$ PS1="$LOGNAME> "

(6)SHELL:当前使用的shell。通常,它的值是/bin/bash。

  • 可以用env命令列出当前环境下的所有环境变量及其值,也可用echo命令察看任何一个环境变量的值。

  • 当更改了环境变量的值以后,往往利用export命令将这些变量输出,使它们成为公用量。例如: $ export HOME PATH PS1

2.6 运算

2.6.1 let命令

bash中执行整数算术运算的命令是let,其语法格式为: let arg …

其中,arg是单独的使用C语言语法的算术表达式。如 let "j=i6+2" let 命令的替代表示形式是: ((算术表达式)) 如 ((j=i6+2))

2.6.2 运算符及其优先级和结合性

其运算符及其优先级和结合性基本上与C语言的相同。

当表达式中有shell的特殊字符时,必须用双引号将其括起来。例如,let “val=a|b”。只有使用**$((算术表达式))**形式才能返回表达式的值,例如 :

$ echo  "((12*9))"	
((12*9))	
$ echo  "$((12*9))"	
108 

2.6.3 关系运算符

关系运算符只支持数字,不支持字符串,除非字符串的值是数字。

2.6.4 算数运算符

注意:条件表达式要放在方括号之间,并且要有空格,例如: [ a = = a== a==b] 是错误的,必须写成 [ $a == $b ]。

2.6.5 布尔运算符

2.6.6 逻辑运算符

2.6.7 字符串运算符

获取字符串长度
# 取得数组元素的个数  
length=${#array_name[@]}  
# 或者  
length=${#array_name[*]}  
# 取得数组单个元素的长度  
lengthn=${#array_name[n]} 

2.6.8 文件测试运算符

文件测试运算符用于检测 Unix 文件的各种属性。

其他检查符:

-S: 判断某文件是否 socket。

-L: 检测文件是否存在并且是一个符号链接。

eg:变量 file 表示文件shellf.sh,它的大小为 100 字节,具有 rwx 权限。

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

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

相关文章

深度学习:基于MindSpore NLP的数据并行训练

什么是数据并行? 数据并行(Data Parallelism, DP)的核心思想是将大规模的数据集分割成若干个较小的数据子集,并将这些子集分配到不同的 NPU 计算节点上,每个节点运行相同的模型副本,但处理不同的数据子集。…

Docker Run使用方法及参数详细说明

Docker Run使用方法及参数详细说明 基本语法常用参数使用示例总结Docker Run是Docker中最基本的命令之一,用于创建并启动一个新的容器。通过Docker Run,用户可以基于指定的镜像创建一个容器实例,并且可以配置容器的各种参数,如网络设置、存储选项等。下面将详细介绍Docker …

QTDemo:串口调试工具

项目简介 本项目通过QT框架设计一款可以在Windows、Linux等平台的跨平台串口助手,串口功能能够满足基本的调试需求。 本项目采用的版本为:QT5.14 visual studio 2022 进行开发。 项目源码:https://github.com/say-Hai/MyCOMDemo 项目页面&am…

【K8S问题系列 | 21 】K8S中如果PV处于Bound状态,如何删除?【已解决】

在Kubernetes(K8S)的存储管理体系中,持久卷(PersistentVolume,PV)是一种重要的资源,它为Pod提供了持久化存储能力。当PV处于Bound状态时,意味着它已经与某个持久卷声明(P…

【行业发展报告】2024大数据与智能化行业发展浅析

回首 2024,大数据智能化浪潮汹涌。海量数据宛如繁星,在智能算法的苍穹下汇聚、碰撞,释放出洞察市场与用户的强大能量,精准勾勒出商业新航线。我们精心雕琢技术架构,从数据存储的坚固基石到处理分析的高效引擎&#xff…

Mumu模拟器12开启ADB调试方法

在使用安卓模拟器进行开发或调试时,ADB(Android Debug Bridge)是一项不可或缺的工具。大多数模拟器默认开启了ADB调试功能,但在安装最新版的 Mumu模拟器12 时,可能会遇到 adb devices 无法识别设备的问题。 问题描述 …

金融租赁系统的创新发展与市场竞争力提升探讨

内容概要 随着经济的快速发展,金融租赁系统逐渐成为金融市场中不可或缺的一环。它不仅提供了灵活的资金解决方案,还促进了企业的资本结构优化与资源配置效率。因此,了解该系统的市场背景与发展现状至关重要。 在现今环境下,新兴…

SQL 实战:基于经纬度的距离计算与位置查询

在位置服务(LBS)系统中,基于地理位置查询和距离计算是核心功能之一。例如: 查找附近的商铺、加油站或医院。计算两点之间的实际直线距离。筛选出指定范围内的用户或设备位置。 MySQL 提供了多种方式实现地理位置查询&#xff0c…

DAY1牛客题库1-3算法题:C语言版本(思路仅供参考)

挑战一下7天刷完牛客题库的108个题,今天是第一天思密达~一直以来都特别懒的做题,还是得勤奋点我觉得~今天只做了3个~嘻嘻明天去玩回家多弄几个~ 1.输出字符串最后一个单词长度 【1】题目: #include"stdio.h" #include"string…

LeetCode 83 :删除排链表中的重复元素

题目: 地址:https://leetcode.cn/problems/remove-duplicates-from-sorted-list/ 方法一: 方法二: package com.zy.leetcode.LeetCode_04;/*** Author: zy* Date: 2024-12-25-15:19* Description: 删除排链表中的里复元素* …

微信流量主挑战:用户破16!新增文档转换(新纪元3)

朋友们,报告好消息!我的小程序用户数量已经涨到16个了!没错,真没拉朋友圈亲戚好友来撑场子,全靠实力(和一点点运气)吸引了16位陌生小伙伴光临!这波进步,连我自己都感动了…

Java-38 深入浅出 Spring - AOP切面增强 核心概念 相关术语 Proxy配置

点一下关注吧!!!非常感谢!!持续更新!!! 大数据篇正在更新!https://blog.csdn.net/w776341482/category_12713819.html 目前已经更新到了: MyBatis&#xff…

基于Docker+模拟器的Appium自动化测试(二)

模拟器的设置 打开“夜神模拟器”的系统设置,切换到“手机与网络”页,选中网络设置下的“开启网络连接”和“开启网络桥接模式”复选框,而后选择“静态IP”单选框,在IP地址中输入“192.168.0.105”,网关等内容不再赘述…

【从零开始入门unity游戏开发之——C#篇36】C#的out协变和in逆变如何解决泛型委托的类型转换问题

文章目录 一、知识回顾和问题分析1、回顾强制转换和as转换知识2、问题分析 二、为什么泛型委托不行?1、泛型类型的严格类型检查2、**as 和强制类型转换不能直接使用** 三、如何解决这个问题?1、**协变(out)**2、**逆变&#xff08…

深度学习使用Anaconda打开Jupyter Notebook编码

新手入门深度学习使用Anaconda打开Jupyter Notebook编码 1. 安装Anaconda 第一种是Anaconda官网下载安装包,但是很慢,不太建议 第二种使用国内清华大学镜像源下载 选择适合自己电脑的版本,支持windows,linux系统 下载完之后自行…

Linux套接字通信学习

Linux套接字通信 代码源码:https://github.com/say-Hai/TcpSocketLearn/tree/CThreadSocket 在网络通信的时候, 程序猿需要负责的应用层数据的处理(最上层),而底层的数据封装与解封装(如TCP/IP协议栈的功能)通常由操作系统、网络协…

git clone 和 conda 换源

文章目录 git clone 通过 sshconda 创建虚拟环境通过 env.yml 文件conda 换源 git clone 通过 ssh git clone ssh://用户名IP地址:/仓库名字.gitconda 创建虚拟环境通过 env.yml 文件 conda env create -f environment.ymlconda 换源 Step 1 生成 .bashrc 文件在家目录下。…

机床数据采集网关在某机械制造企业的应用

随着工业4.0时代的到来,智能制造已成为制造业转型升级的重要方向。数控机床作为现代制造业的核心设备,其运行状态和加工参数的数据实时采集与分析对于提升生产效率、优化生产流程具有关键意义。 背景概述 某机械制造企业拥有多台数控机床,这…

c# RSA加解密工具,.netRSA加解密工具

软件介绍 名称: c# RSA加解密工具,.netRSA加解密工具依赖.net版本: .net 8.0工具类型: WinForm源码下载 c# RSA加解密工具,.netRSA加解密工具 依赖项 WinFormsRSA.csproj <Project

穷举vs暴搜vs深搜vs回溯vs剪枝_全排列_子集

46. 全排列 递归解决&#xff1a;一开始选一个数&#xff0c;递归进入下一层再选一个新的数&#xff0c;直到到最后一个数。反会上一层遍历其它数。 每次递归到叶子节点就找到了一种组合&#xff0c;思路有了具体怎么实现&#xff1f; 1.怎么记录每条路径&#xff1f; 定义一个…