当前位置: 首页 > article >正文

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

文章一览

  • 前言
  • 一、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.kler.cn/a/453585.html

相关文章:

  • Linux:code:network:devinet_sysctl_forward;IN_DEV_FORWARD
  • 简单园区网拓扑实验
  • TP5 动态渲染多个Layui表格并批量打印所有表格
  • SwiftUI 入门趣谈:在文本框(TextField)内限制数字的输入
  • 有没有免费提取音频的软件?音频编辑软件介绍!
  • 在JavaScript中,let 和 const有什么不同
  • 链游破局之路:如何打破边缘化,获得更好的发展
  • [Unity Shader]【图形渲染】 Shader数学基础13-模型空间,世界空间和观察空间的转换
  • GPIO+TIM(无PWM)实现呼吸灯功能
  • Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena
  • mysql三种读取模式(普通、流式、游标)
  • node.js web框架koa的使用
  • Sealos Devbox 基础教程:使用 Cursor 从零开发一个 One API 替代品
  • ip-协议
  • OpenAI 12天发布会:AI革命的里程碑@附35页PDF文件下载
  • C语言练习-if语句
  • 【JavaEE】网络(6)
  • vulnhub靶场【shuriken】之node
  • 如何永久解决Apache Struts文件上传漏洞
  • Matrix-Breakout 2 Morpheus(找到第一个flag)
  • Linux下比ack更快的ag搜索命令详解
  • 基于QT(C++)+MySQL实现的旅行模拟器
  • Idea 添加tomcat 并发布到tomcat
  • ubuntu22.04安装PPOCRLabel
  • 踏踏实实练SQLday1-2 lead/lag使用(股票波峰波谷)
  • cesium通过经纬度获取3dtiles 得feature信息