一文了解什么是 Linux 上的包依赖

冬静姑娘_5214

冬静姑娘_5214

2024-02-12

774人浏览

转载

使用这些编码技巧编写快速、可读的 shell 脚本。

Bash 无疑已经成为每个现代类 Unix 系统或基于 Unix 的操作系统的本地内置自动化解决方案。程序员使用 Bash 创建 Shell 脚本来自动化重复的命令行任务。Bash 的主要目标是提供一种最小的语法来执行其他程序并处理它们的退出代和输出。但是,现代的 Bash 解释器具有完整的命令语言,提供大多数通用编程语言的功能。因此,我们可以通过包含传统的命令行调用和算法代码编写高度可读的Shell脚本。现代的Bash版本引入了关联数组和支持按引用传递的性能相关特性,使 Bash 具有与其他准备好进行 Shell 脚本编写的语言竞争的能力。

在本文中,我将介绍一些 Bash 编码技巧,您可以在您的 Shell 脚本中包含它们,使它们现代化、快速和可读。使用这些技巧,您可以使用 Bash 编写通用编程或算法实现,例如算法原型、实现实用程序,甚至是竞争编程!

在 Shell 脚本中使用数组

传统的 Bash 变量通常没有类型,但是您可以根据特定的处理上下文将其处理为整数、小数或字符串。我们通常使用Bash变量来存储命令输出、算法参数和其他临时值。Bash还支持两种数组类型:一维(按数字索引)和关联(键值结构)。与其他流行的动态类型通用语言(例如Python、PHP 或 JavaScript)一样,使用 Bash 数组非常容易。以下是如何在 Bash 中创建数组的方法:

#!/bin/bash
#Linux迷 www.linuxmi.com

numbers=(9 3 1 3 9)

declare -a words
words[0]='Linux迷'
words[1]='LinuxMi'

echo ${numbers[@]} ${words[@]}

以上代码输出的数组内容如下:

一文了解什么是 Linux 上的包依赖

您可以通过 declare 内置命令检查每个数组引用的声明,如下所示:

一文了解什么是 Linux 上的包依赖

在 Bash 中检查数组声明,作者的屏幕截图 您还可以使用最小的语法进行数组操作和处理活动,例如追加新项、删除现有项、处理数组元素、排序等。例如,以下代码删除无效的分数值并打印前三个最高分数:

#!/bin/bash
#Linux迷 www.linuxmi.com

declare -a marks
marks+=(75 65 80 102 26) # class A marks
marks+=(103 68) # class B marks

# 删除无效标记
for i in "${!marks[@]}"; do
    if ((marks[i] > 100)); then
        unset "marks[$i]"
    fi
done

# 对所有标记进行排序
marks_s=($(printf '%s\n' "${marks[@]}" | sort -nr))

# 打印前 3 名
echo ${marks_s[0]} ${marks_s[1]} ${marks_s[2]}
一文了解什么是 Linux 上的包依赖

以上代码会生成一个单独的进程进行排序,因为我们使用了 sort 外部命令,但是您可以通过使用一些 Bash 代码实现简单的排序算法,例如选择排序,来避免这种情况。

创建映射或字典

在一些编程场景中,我们需要在 shell 脚本中存储键值对数据。程序员通常使用键值数据结构来创建字典结构、映射和缓存容器(通过记忆化)。如果您使用 Python 编写您的 shell 脚本,您可以使用内置的字典数据结构来存储键值数据。如何在 Bash 中使用字典结构?

Bash 4.0 版本引入了关联数组功能,用于存储键值数据。下面是一个 Bash 关联数组的简单示例:

#!/bin/bash
#Linux迷 www.linuxmi.com

declare -A marks=([linux]=39 [ubuntu]=27 [debian]=83 [fedora]=59)

for key in "${!marks[@]}"; do
    printf "$key \t ${marks[$key]} \n"
done

在这里,我们使用了 !mapvar[@] 语法来提取所有字典键作为数组进行迭代。上述代码将打印出所有键和对应的值,如下所示:

一文了解什么是 Linux 上的包依赖

Bash 让你可以使用最少的语法来操作和访问关联数组数据。使用Bash关联数组的方式就像使用 Python 字典一样。请看下面的例子:

#!/bin/bash
#Linux迷 www.linuxmi.com

read -p "Enter coords (i.e., [x]=10 [y]=12): " coords
declare -A "coords=($coords)"

if [ ! -v "coords[x]" ]; then
    coords[x]=5
fi

if [ ! -v "coords[y]" ]; then
    coords[y]=10
fi

for key in "${!coords[@]}"; do
    printf "$key = ${coords[$key]} \n"
done

以上源代码向用户请求x和y坐标,为缺失的坐标轴值设置默认值,并在终端上打印它们。在这里,我们使用! -v语法,因为通常我们使用 Python 字典中的 not in。

实现命名参数支持

当您通过 Bash 解释器执行 shell 脚本时,操作系统会创建一个新的 Bash 进程,并将您的脚本文件作为第一个命令行参数。操作系统通常允许您将一系列参数传递给每个操作系统进程。当您为其他命令/进程提供命令行参数时,您也可以将它们传递到您的 Bash 脚本中。假设您需要将两个整数值传递给脚本。然后,您可以轻松使用 和2 分别访问第一个和第二个参数值。但是,当您使用更多索引参数并且需要实现可选参数(也称为命令行标志或选项)时,事情将变得复杂。

作为这种情况的解决方案,您可以使用内置的 getopts 来使用命名参数。使用以下 shell 脚本,我们可以覆盖一些脚本中的默认值:

Obsidian (Linux)
Obsidian (Linux)

操作 Obsidian 库(纯 Markdown 笔记),并通过 notesmd-cli 实现自动化。

下载
#!/bin/bash
#Linux迷 www.linuxmi.com

title="Linux迷 www.linuxmi.com"
message="Hello world!www.linuxmi.com  Linux迷"

while getopts ":t:m:" option; do
    echo $option
    case "${option}" in
        t)
            title=${OPTARG}
            ;;
        m)
            message=${OPTARG}
            ;;
    esac
done

zenity --info --title="$title" --text="$message"
一文了解什么是 Linux 上的包依赖

默认情况下,上面的脚本显示一个带有默认标题和消息的 GTK 消息框,但是您可以使用命名的命令行参数来覆盖它们,如下所示:

./linuxmi.com.sh -t "hello"

./linuxmi.com.sh -m "world"
一文了解什么是 Linux 上的包依赖

getopts 内置支持仅使用单个字母选项。您可以使用 getopt 来使用长形式选项(即–title),如此 gist 所示。

使用函数中的引用传递

引用传递是一种编程语言特性,它允许您通过内存引用将数据传递到函数中,而不是将整个数据段复制到新变量中。C ++ 程序员总是努力编写性能优先的代码,对于类对象,结构体和字符串,使用引用传递而不是值传递。

如果您使用的是 Bash 4.3 或更新版本,则可以使用名称引用在 shell 脚本中实现引用传递。以下是一个简单的示例代码片段,通过函数更改字符串变量:

#!/bin/bash
#Linux迷 www.linuxmi.com

function change_str_var() {
    local str_new="Bash"
    local -n str_ref=$1
    echo "$str_ref -> $str_new" # Python -> Bash
    str_ref=$str_new
}

str="Python"
change_str_var str
echo $str # Bash
一文了解什么是 Linux 上的包依赖

上述 change_str_var 函数使用 local 命令创建一个局部的 str_ref 引用,引用全局的 str 变量。然后,它通过覆盖旧字符串值来分配一个新的字符串值。

一些程序员在函数内部使用 echo 命令,并通过命令替换特性调用特定函数以从 Bash 函数返回值(因为原生 Bash return 关键字仅支持返回有效的退出代码)。这会生成另一个子 shell 并消耗更多资源。因此,现在程序员可以使用引用传递并编写性能优先的Bash函数返回,如果他们使用新的 Bash 版本。

使用类型和修饰符属性的变量

Bash 被称为一种无类型命令语言。换句话说,它通常将变量数据处理为字符串,但根据上下文(例如在算术扩展中)进行相应处理。另一方面,Bash 也允许程序员使用类型属性,并提供两种内置的数组类型。即使有了这些功能,我们也不能将 Bash 视为纯动态类型语言,但这些变量属性将Bash置于无类型和动态类型语言之间。

Bash 支持使用整数变量属性将特定变量标记为整数。一旦创建了一个整数变量,当您分配非整数值时,Bash 会发出警告,如下所示:

一文了解什么是 Linux 上的包依赖

Bash 还允许使用 declare -r 命令创建常量。每当您的脚本尝试更改常量时,Bash 会在屏幕上打印错误消息。此外,正如我们之前使用的那样,您可以使用 declare 内置函数创建数组。

Bash 还允许您为变量添加一些修饰符属性。例如,您可以创建仅包含小写字母或大写字母的字符串,如下所示:

declare -l lc_str="Hello World"
declare -u uc_str
uc_str="Hello"
uc_str="World"

echo $lc_str # hello world
echo $uc_str # WORLD
一文了解什么是 Linux 上的包依赖

使用 Bash 变量属性,您可以编写更少出错、更易读、更现代的 shell 脚本。

相关:Bash 特殊变量(,?,#,@,$$,$*) 见 https://www.linuxmi.com/bash-special-variables.html

如果还有什么疑问与建议,请在评论栏里给我们留言。感谢您的阅读。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

2023.10.24

6224

49

sort排序函数用法
sort排序函数用法

sort排序函数的用法:1、对列表进行排序,默认情况下,sort函数按升序排序,因此最终输出的结果是按从小到大的顺序排列的;2、对元组进行排序,默认情况下,sort函数按元素的大小进行排序,因此最终输出的结果是按从小到大的顺序排列的;3、对字典进行排序,由于字典是无序的,因此排序后的结果仍然是原来的字典,使用一个lambda表达式作为key参数的值,用于指定排序的依据。

2023.09.04

1158

7

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.03

1838

5

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.04

2904

5

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

2023.10.24

6224

49

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

2023.11.24

6069

6

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

2024.03.22

7674

16

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

2024.04.29

11534

11

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

2025.07.29

5939

17

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习

Buffalo框架快速入门指南
Buffalo框架快速入门指南

共0课时 | 0人学习

Valgrind支持平台说明
Valgrind支持平台说明

共0课时 | 0人学习