01 Shell 编程规范与变量

目录

1.1 Shell脚本概述

        1.1.1 Shell的作用

        1.1.2 编写第一个Shell脚本

        1.1.3 重定向与管道操作

                1. 重定向操作

                        1. 重定向输出

                        2. 重定向输入

                        3. 错误重定向

                2. 管代操作

1.2 Shell变量的作用、类型

        1.2.1 自定义变量

                1. 定义新的变量

                2. 查看和引用变量的值

                3. 变量赋值的特殊操作

                        1. 双引号("")

                        2. 单引号('')

                        3. 反撇号(``)

                        4. read命令

                4. 设置变量的作用范围

                5. 数制变量的运算

        1.2.2 特殊的Shell变量

                1. 环境变量

                2. 只读变量

                3. 位置变量

                4. 预定义变量


1.1 Shell脚本概述

        在一些复杂的Linux维护工作中,大量重复性的输入和交互操作不仅费时费力,而且容易出错,而编写一个恰到好处的 Shell脚本程序,可以批量处理、自动化地完成一系列维护任务,大大减轻管理员的负担。

        1.1.1 Shell的作用

        Linux系统中的Shell是一个特殊的应用程序,它介于操作系统内核与用户之间,充当了一个“命令解释器"的角色,负责接收用户输入的操作指令(命令)并进行解释,将需要执行的操作传递给内核执行,并输出执行结果。

        常见的 Shell解释器程序有很多种,使用不同的Shell时,其内部指令、命令行提示符等方面会存在一些区别。通过letclshells 文件可以了解当前系统所支持的Shell脚本种类。

        1.1.2 编写第一个Shell脚本

        Bash ( /bin/bash)是目前大多数Linux版本采用的默认Shell。Bash 的全称为BourneAgain Shell,是最受欢迎的开源软件项目之一。

        那么,什么是"Shell脚本"呢?简单地说,只要将平时使用的各种Linux 命令按顺序保存到一个文本文件中,然后添加可执行权限,这个文件就成为一个 Shell脚本了。例如,执行以下操作可以创建第一个脚本文件: first.sh。

        上述first.sh脚本文件中,包括三条命令: cd /bootl、pwd、Is -.h vml*。执行此脚本文件后,输出结果与依次单独执行这三条命令是相同的,从而实现了“批量处理"的自动化过程。

        当然,一个合格的 Shell脚本程序应该遵循标准的脚本结构,而且能够输出友好的提示信息,更加容易读懂。对于代码较多,结构复杂的脚本,应添加必要的注释文字。改写后的first.sh脚本内容如下所示。

        上述first.sh脚本文件中,第一行“#!/bin/bash"是一行特殊的脚本声明,表示此行以后的语句通过/bin/bash程序来解释执行;其他以"#"开头的语句表示注释信息;echo命令用于输出字符串,以使脚本的输出信息更容易读懂。例如,执行改写后的 first.sh脚本,输出结果如下所示。

        当前的目录位于:

/boot

         其中以vml开头的文件包括:

        

        直接通过"./first.sh"的方式执行脚本,要求文件本身具有×权限,在某些安全系统中可能无法满足此条件。鉴于此,Linux操作系统还提供了执行 Shell脚本的其他方式——指定某个Shell来解释脚本语句,或者通过内部命令source(或点号".")来加载文件中的源代码执行。例如,使用"sh first.sh"或". first.sh”也可以执行first.sh脚本中的语句。

        或

        Linux系统中包括大量的 Shell脚本文件,在学习Shell脚本的过程中可用来作为参考,但应尽量避免直接修改系统内的Shell脚本文件,以免导致服务或系统故障。

        1.1.3 重定向与管道操作

        由于Shell脚本“批量处理"的特殊性,其大部分操作过程以静默方式运行,不需要用户进行干预。因此学会提取、过滤执行信息变得十分重要。本小节主要介绍 Shell环境中的两个IIO操作:重定向和管道。

                1. 重定向操作

        Linux系统使用文件来描述各种硬件、设备等资源,如以前学过的硬盘和分区、光盘等设备文件。用户通过操作系统处理信息的过程中,包括以下几类交互设备文件。

  1. 标准输入(STDIN):默认的设备是键盘,文件编号为0,命令将从标准输入文件中读取在执行过程中需要的输入数据。
  2. 标准输出(STDOUT):默认的设备是显示器,文件编号为1,命令将执行后的输出结果发送到标准输出文件。
  3. 标准错误(STDERR):默认的设备是显示器,文件编号为2,命令将执行期间的各种错误信息发送到标准错误文件。

        标准输入、标准输出和标准错误默认使用键盘和显示器作为关联的设备,与操作系统进行交互,完成最基本的输入、输出操作,即从键盘接收用户输入的各种命令字串、辅助控制信息,并将命令结果输出到屏幕上;如果命令执行出错,也会将错误信息反馈到屏幕上。

        在实际的Linux系统维护中,可以改变输入、输出内容的方向,而不使用默认的标准输入、输出设备(键盘和显示器),这种操作称为重定向。

                        1. 重定向输出

        重定向输出指的是将命令的正常输出结果保存到指定的文件中,而不是直接显示在显示器的屏幕上。重定向输出使用“>"或“>>"操作符号,分别用于覆盖或追加文件。

        若重定向输出的目标文件不存在,则会新建该文件,然后将前面命令的输出结果保存到该文件中;若目标文件已经存在,则将输出结果覆盖或追加到文件中。例如,若要将当前主机的CPU类型信息(uname -p)保存到 kernel.txt文件中,而不是直接显示在屏幕上,可以执行以下操作。

        当需要保留目标文件原有的内容时,应改用“>"操作符号,以便追加内容而不是全部覆盖。

        例如,执行以下操作可以将内核版本信息追加到 kernel.txt文件中。

                        2. 重定向输入

        重定向输入指的是将命令中接收输入的途径由默认的键盘改为指定的文件,而不是等待从键盘输入。重定向输入使用“<""操作符。

        通过重定向输入可以使一些交互式操作过程能够通过读取文件来完成。例如,使用passwd命令为用户设置密码时,每次都必须根据提示输入两次密码字串,非常烦琐,若改用重定向输入将可以省略交互式的过程,而自动完成密码设置(结合passwd命令的"--stdin"选项来识别标准输入)。

        非交互式命令语句可以更方便的在Shell脚本中使用,从而大大减少程序被打断的过程,提高脚本执行的效率。

                        3. 错误重定向

        错误重定向指的是将执行命令过程中出现的错误信息(如选项或参数错误等)保存到指定的文件,而不是直接显示在屏幕上。错误重定向使用""2>"操作符,其中“2"是指错误文件的编号(在使用标准输出、标准输入重定向时,实际上省略了1、0编号)。

        在实际应用中,错误重定向可用来收集程序执行的错误信息,为排错提供依据;对于Shell脚本,还可以将无关紧要的错误信息重定向到空文件/dev/null中,以保持脚本输出的简洁。例如,执行以下操作可以将使用tar命令进行备份时出现的错误信息保存到error.log文件中。

        使用“2>"操作符时,会像使用“>"操作符一样覆盖目标文件的内容,若要追加内容而不是覆盖文件,则应改用"2>>"操作符。

        当命令输出的结果可能既包括标准输出(正常执行〉信息,又包括错误输出信息时,可以使用操作符“>""2>"将两类输出信息分别保存到不同的文件,也可以使用“&>"操作符将两类输出信息保存到同一个文件。例如,在编译源码包的自动化脚本中,若要忽略make、makeinstall等操作过程信息,则可以将其定向到空文件/dev/null。

                2. 管代操作

        管道(pipe)操作为不同命令之间的协同工作提供了一种机制,位于管道符号""左侧的命令输出的结果,将作为右侧命令的输入(处理对象),同一行命令中可以使用多个管道。

        在Shell脚本应用中,管道操作通常用来过滤所需要的关键信息。例如,使用grep命令查询使用/bin/bash作为Shell的系统用户名时,会输出符合条件的整行内容,在此基础上可以结合管道操作与awk命令做进一步过滤,只输出用户名和登录 Shell列。

        上例中 awk命令的作用是以冒号“"作为分隔,输出第1个、第7个区域的字符串。其中的"-F"部分用来指定分隔符号(未指定时,默认以空格或制表符分隔)。

        又如,若要提取根分区(/)的磁盘使用率信息,可以执行以下操作,其中用到了df、grep、 awk命令和管道操作。

        重定向与管道操作是Shell环境中十分常用的功能,若能够熟练掌握并灵活运用,将有助于编写代码简洁但功能强大的Shell脚本程序。

1.2 Shell变量的作用、类型

        各种 Shell环境中都使用到了“变量"的概念。Shell变量用来存放系统和用户需要使用的特定参数(值),而且这些参数可以根据用户的设定或系统环境的变化而相应变化。通过使用变量,Shell程序能够提供更加灵活的功能,适应性更强。

        常见Shell变量的类型包括自定义变量、环境变量、只读变量、位置变量、预定义变量。

        1.2.1 自定义变量

        自定义变量是由系统用户自己定义的变量,只在用户自己的Shell环境中有效,因此又称为本地变量。在编写Shell脚本程序时,通常会设置一些特定的自定义变量,以适应程序执行过程中的各种变化,满足不同的需要。

        定义变量的基本格式为“变量名=变量值",等号两边没有空格。变量名称需以字母或下划线开头,名称中不要包含特殊字符(如+、-、*、l、.、?、%、&、#等〉。例如,若要定义一个名为“Product"的变量(值为Python)和一个名为""Version"的变量(值为2.7.13),可以执行以下操作。

                1. 定义新的变量

        通过在变量名称前添加前导符号"$",可以引用一个变量的值。使用echo命令可以查看变量,可以在一条echo命令中同时查看多个变量值。

        当变量名称容易和紧跟其后的其他字符相混淆时,需要添加大括号“"将其括起来,否则将无法确定正确的变量名称。对于未定义的变量,将显示为空值。

                2. 查看和引用变量的值

        通过在变量名称前添加前导符号“$",可以引用一个变量的值。使用echo命令可以查看变量,可以在一条echo命令中同时查看多个变量值。

        当变量名称容易和紧跟其后的其他字符相混淆时,需要添加大括号“}"将其括起来,否则将无法确定正确的变量名称。对于未定义的变量,将显示为空值。

                3. 变量赋值的特殊操作

        在等号“="后边直接指定变量内容是为变量赋值的最基本方法,除此之外,还有一些特殊的赋值操作,可以更灵活地为变量赋值,以便适用于各种复杂的管理任务。

                        1. 双引号("")

        双引号主要起界定字符串的作用,特别是当要赋值的内容中包含空格时,必须以双引号括起来;其他情况下双引号通常可以省略。

        例如,若要将Python 2.7.13赋值给变量PYTHON,应执行PYTHON="Python 2.7.13"操作。

        在双引号范围内,使用“"$""符号可以引用其他变量的值(变量引用),从而能够直接调用现有变量的值来赋给新的变量。例如,执行以下操作可以调用变量Version 的值,将其赋给一个新的变量PyVersion,最终的值为"Python 2.7.13”"。

                        2. 单引号('')

        当要赋值的内容中包含$、“、I等具有特殊含义的字符时,应使用单引号括起来。在单引号的范围内,将无法引用其他变量的值,任何字符均作为普通字符看待。但赋值内容中包含单引号(‘)时,需使用N符号进行转义,以免冲突。

                        3. 反撇号(``)

        反撇号主要用于命令替换,允许将执行某个命令的屏幕输出结果赋值给变量。反撇号括起来的范围内必须是能够执行的命令行,否则将会出错。例如,若要在一行命令中查找useradd命令程序的位置并列出其详细属性,可以执行以下操作。

        

        上述操作相当于连续执行了两条命令——先通过 which useradd命令查找出useradd命令的程序位置,然后根据查找结果列出文件属性。执行过程中,会用which useradd 命令的输出结果替换整个反撤号范围。

        需要注意的是,使用反撤号难以在一行命令中实现嵌套命令替换操作,这时可以改用“$()"来代替反撇号操作,以解决嵌套的问题。例如,若要查询提供 useradd命令程序的软件包所安装的配置文件位置,可以执行以下操作(从里到外先后执行替换)。

                        4. read命令

        除了上述赋值操作以外,还可以使用Bash 的内置命令read来给变量赋值。read命令用来提示用户输入信息,从而实现简单的交互过程。执行时将从标准输入设备(键盘〉读入一行内容,并以空格为分隔符,将读入的各字段依次赋值给指定的变量(多余的内容赋值给最后一个变量)。若指定的变量只有一个,则将整行内容赋值给此变量。

        例如,执行以下操作将会等待用户输入文字,并将输入的内容赋值给变量ToDir1。

        为了使交互式操作的界面更加友好,提高易用性,read命令可以结合"-p"选项来设置提示信息,以便告知用户应该输入什么内容等相关事项。例如,若希望提示用户输入备份文件的存放目录,并将输入的路径信息赋值给变量ToDir2,可以执行以下操作。

                4. 设置变量的作用范围

        默认情况下,新定义的变量只在当前的 Shell环境中有效,因此称为局部变量。当进入子程序或新的子Shell环境时,局部变量将无法再使用。例如,直接执行Bash进入一个新的子 Shell脚本后,将无法引用父级 Shell环境中定义的Product、Version等变量。

        为了使用户定义的变量在所有的子Shell环境中能够继续使用,减少重复设置工作,可以通过内部命令export将指定的变量导出为全局变量。用户可以同时指定多个变量名称作为参数(无须使用“$"符号),变量名之间以空格分隔。

        使用export导出全局变量的同时,也可以为变量进行赋值,这样在新定义全局变量时就不需要提前进行赋值了。例如,执行以下操作可以直接新建一个名为FQDN的全局变量。

                5. 数制变量的运算

        Shell变量的数值运算多用于脚本程序的过程控制(如循环次数、使用量比较等,后续章节会介绍)。在 Bash Shell环境中,只能进行简单的整数运算,不支持小数运算。整数值的运算主要通过内部命令expr进行,基本格式如下所示。需要注意,运算符与变量之间必须有至少一个空格。

expr 变量1 运算符 变量2 [运算符 变量3]...

        其中,变量1、变量2.....对应为需要计算的数值变量(需要以"$"符号调用),常用的几种运算符如下所述。

  1. +:加法运算
  2. -:减法运算
  3. \*:乘法运算,注意不能仅使用“*”符后,否则将被当成文件通配符
  4. /:除法运算
  5. %:求模运算,又称为取余运算,用来计算数值相除后的余数

        以下操作设置了×(值为35)、Y(值为16)两个变量,并依次演示了变量X、Y的加、减、乘、除、取模运算结果。

        若要将运算结果赋值给其他变量,可以结合命令替换操作(使用反撤号)。例如,计算变量Y的3次方,并将结果赋值给变量Ycube。

        1.2.2 特殊的Shell变量

        除了用户自行定义的 Shell变量以外,在Linux系统和 Bash Shell环境中还有一系列的特殊变量——环境变量、只读变量、位置变量、预定义变量。下面分别进行介绍。

                1. 环境变量

        环境变量指的是出于运行需要而由Linux系统提前创建的一类变量,主要用于设置用户的工作环境,包括用户宿主目录、命令查找路径、用户当前目录、登录终端等。环境变量的值由Linux系统自动维护,会随着用户状态的改变而改变。

        使用env命令可以查看到当前工作环境下的环境变量,对于常见的一些环境变量应了解其各自的用途。例如,变量USER表示用户名称,HOME表示用户的宿主目录,LANG表示语言和字符集,PWD表示当前所在的工作目录,PATH表示命令搜索路径等。

        PATH变量用于设置可执行程序的默认搜索路径,当仅指定文件名称来执行命令程序时,Linux系统将在PATH变量指定的目录范围查找对应的可执行文件,如果找不到则会提示"command not found"。例如,first.sh脚本位于lroot目录下,若希望能直接通过文件名称来运行脚本,可以修改PATH变量以添加搜索路径,或者将first.sh脚本复制到现有搜索路径中的某个文件夹下。

        在Linux系统中,环境变量的全局配置文件为letc/profile,在此文件中定义的变量作用于所有用户。除此之外,每个用户还有自己的独立配置文件(~l.bash_profile)。若要长期变更或设置某个环境变量,应在上述文件中进行设置。例如,执行以下操作可以将记录的历史命令条数改为200条(默认为1000条〉,只针对root用户。

        上述修改只有当root用户下次登录时才会生效。若希望立即生效,应手动修改环境变量,或者可以加载配置文件执行。

                2. 只读变量

        Shell变量中有一种特殊情况,一经设定,其值是不可改变的,这种变量被称为只读变量。在创建变量的时候可将其设置为只读属性,也可以将已存在的变量设置为只读属性,只读变量主要用于变量值不允许被修改的情况。例如脚本中定义了一个变量"log_path"用来定义日志文件的路径,在脚本的执行过程中如果不想被修改,就可以将该变量设置为只读变量。使用readonly 命令将变量定义为只读变量,定义之后不能通过再次赋值的方式进行修改。

        上述unset命令通常用于删除变量。

                3. 位置变量

        为了在使用Shell脚本程序时,方便通过命令行,为程序提供操作参数,Bash引入了位置变量的概念。当执行命令行操作时,第一个字段表示命令名或脚本程序名,其余的字符串参数按照从左到右的顺序依次赋值给位置变量。

        位置变量也称为位置参数,使用$1、$2、$3、...、$9表示。例如,当执行命令行"Is -lh/boot"时,其中第1个位置变量为"-Ih",以"$1"表示;第2个位置变量为".boot",以"$2"表示。命令或脚本本身的名称使用“$0"表示,虽然$0与位置变量的格式相同,但是$0属于预定义变量而不是位置变量。

        为了说明位置变量的作用,下面编写一个加法运算的小脚本 adder2num.sh,用来计算两个整数的和。需要计算的两个整数在执行脚本时以位置变量的形式提供。

                4. 预定义变量

        预定义变量是由Bash程序预先定义好的一类特殊变量,用户只能使用预定义变量,而不能创建新的预定义变量,也不能直接为预定义变量赋值。预定义变量使用“$"符号和另一个符号组合表示,较常用的几个预定义变量的含义如下。

  1. $#:表示命令行中位置参数的个数。
  2. $*:表示所有位置参数的内容。
  3. $?:表示前一条命令执行后的返回状态,返回值为О表示执行正确,返回任何非О值均表示执行出现异常。
  4. $0:表示当前执行的脚本或程序的名称。

        为了说明预定义变量的作用,下面编写一个备份操作的小脚本,用来打包命令行指定的多个文件或目录,并输出相关信息。其中,新建的压缩包文件名称中嵌入UNI时间戳(从1970年1月1日至今经过的秒数),通过"date +%s"命令获取。

 

      

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Django使用django-apscheduler实现定时任务

定时任务可以在后台定时执行指定的代码&#xff0c;避免了很多人为操作。下面是在Django项目中如何使用定时任务的具体操作流程。 我在这里使用的 django-apscheduler库来实现定时任务。 一、安装 django-apscheduler pip install django-apscheduler二、在项目的setting.py…

java.io.eofexception:ssl peer shut down incorrectly

可能是因为 1)https设置 2&#xff09;超时设置 FeignConfig.java package zwf.service;import java.io.IOException; import java.io.InputStream; import java.security.KeyStore;import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory;import org.apac…

PXE高效批量网络装机(补充) 实验部分

然后把防火墙、安全机制全都给关闭掉&#xff0c;不要让它们干扰后续的实验&#xff1a; 然后安装那几个需要用到的软件包&#xff1a; 如果重启了系统vsftpd是不能自动启动起来的&#xff0c;如果想让该服务每次开机都自动的启动起来&#xff0c;可以执行下图中的命令&#xf…

关系数据理论

什么是关系数据理论&#xff1a;用来评判数据库逻辑设计“好坏程度”的标准&#xff1b;二是如果逻辑设计中存在“不好”的关系模式&#xff0c;如何将其修改为“好”的关系模式。 函数依赖&#xff1a;举个例子:学生表中&#xff0c;一个学生的学生号确定了&#xff0c;学生的…

Arduino平台软硬件原理及使用——无源蜂鸣器模块的使用

文章目录 一、蜂鸣器发声原理 二、无源蜂鸣器与有源蜂鸣器的区分 三、无源蜂鸣器模块在Arduino中的使用 一、蜂鸣器发声原理 上图为常见的不同封装及规格的蜂鸣器。 同蜜蜂、知了等昆虫发声原理一样&#xff0c;蜂鸣器同样靠振动来发出声音&#xff1b; 如上图为无源蜂鸣器的内…

whiteboard - 笔记

1 drawio draw.io GitHub - jgraph/drawio: draw.io is a JavaScript, client-side editor for general diagramming. 2 demo 可以将XML数据保存到服务器上的data目录。需要在服务器端创建一个接收和处理POST请求的脚本,该脚本将接收到的SVG数据保存到指定的文件中。下面是…

subversion

subversion Install # CentOS安装Subversion yum install subversion mkdir /var/svn/ systemctl restart svnserve# Docker安装Subversion&#xff08;参考&#xff1a;https://github.com/garethflowers/docker-svn-server&#xff09; docker run \--name my-svn-server \…

《C++ Primer》导学系列:第 6 章 - 函数

6.1 函数基础 6.1.1 基本概念 函数是C程序的基本组成单元&#xff0c;用于将代码组织成可以复用的模块。函数通过函数名进行调用&#xff0c;并且可以接受参数和返回值。函数的定义包括函数头和函数体&#xff0c;其中函数头描述了函数的接口&#xff0c;函数体包含了具体的实…

RabbitMQ 开发指南

连接RabbitMQ 连接方式一&#xff1a; 也可以选择使用URI的方式来实现 连接方式二&#xff1a; Connection接口被用来创建一个Channel&#xff0c;在创建之后&#xff0c;Channel可以用来发送或者接收消息。 Channel channel conn.createChannel();使用交换器和队列 声明…

基于Java的留守儿童爱心网站

你好呀&#xff0c;我是计算机学姐码农小野&#xff01;如果有相关需求&#xff0c;可以私信联系我。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;B/S结构&#xff0c;SpringBoot框架 工具&#xff1a;MyEclipse&#xff0c;Navicat&#xff0c;To…

全球森林碳通量(2001-2023年)数据集

简介 全球森林碳通量&#xff08;2001-2023&#xff09; 森林碳净通量表示 2001-2023 年间森林与大气之间的碳净交换量&#xff0c;计算方法是模型期内森林排放的碳与森林清除&#xff08;或封存&#xff09;的碳之间的平衡&#xff08;兆克 CO2 排放量/公顷&#xff09;。碳净…

【PB案例学习笔记】-20制作一个超链接按钮

写在前面 这是PB案例学习笔记系列文章的第19篇&#xff0c;该系列文章适合具有一定PB基础的读者。 通过一个个由浅入深的编程实战案例学习&#xff0c;提高编程技巧&#xff0c;以保证小伙伴们能应付公司的各种开发需求。 文章中设计到的源码&#xff0c;小凡都上传到了gite…

【机器学习】基于稀疏识别方法的洛伦兹混沌系统预测

1. 引言 1.1. DNN模型的来由 从数据中识别非线性动态学意味着什么&#xff1f; 假设我们有时间序列数据&#xff0c;这些数据来自一个&#xff08;非线性&#xff09;动态学系统。 识别一个系统意味着基于数据推断该系统的控制方程。换句话说&#xff0c;就是找到动态系统方…

生成式AI时代,数据存储管理与成本如何不失控?

无数据&#xff0c;不AI。 由生成式AI掀起的这一次人工智能浪潮&#xff0c;对企业的产品、服务乃至商业模式都有着颠覆性的影响。因此&#xff0c;在多云、大数据、生成式AI等多元技术的驱动下&#xff0c;数据要素变得愈发重要的同时&#xff0c;企业对于数据存储的需求也在…

LabVIEW开发扫描隧道显微镜

扫描隧道显微镜利用量子隧穿效应&#xff0c;通过一个极细的探针在样品表面上进行扫描&#xff0c;测量隧穿电流的变化&#xff0c;以得到样品表面的原子级别图像。探针与样品之间的距离非常小&#xff08;约1纳米&#xff09;&#xff0c;隧穿电流对距离变化极其敏感&#xff…

全能AI客户端:ChatGPT Web Midjourney Proxy,AI绘画+GPT4o对话

这绝对是目前最全能的 AI 客户端&#xff0c;ui 界面集成 ChatGPT AI 对话、Midjourney AI 画图、Suno AI 音乐等等市面主流的 AI 功能&#xff0c;只需绑定一个 API key 即可使用全部 AI 功能&#xff0c;Midjourney 甚至比官方好用几倍&#xff01; 项目简介 ChatGPT Web Mi…

【嵌入式开发】STM32+USB的快速开发

目录 一、概述 二、STM32+USB开发流程 2.1 建立新的工程 2.2 系统配置 2.3 时钟配置 2.4 操作系统 2.5 选择USB配置 2.6 在USB_HOST中选择支持的子类(class) 2.7 Clock 配置 三、注意事项 3.1 应用驱动配置 3.2 上电调试基础工作 一、概述 USB作为大家耳熟能详的…

【上海交大】博士生年度进展报告模板

上海交通大学 博士生年度进展报告模板 比较不好找&#xff0c;在交我办中发起申请流程后才能看到链接&#xff0c;链接如下&#xff1a; https://www.gs.sjtu.edu.cn/xzzx/pygl/15

【Python】使用OpenCV特征匹配检测图像中的【特定水印】

如果没有方向 往哪里走都是前方 做自己的光 不需要多亮 曾受过的伤 会长出翅膀 大雨冲刷过的天空会更加明亮 流过泪的眼睛也一样 做自己的光 悄悄的发亮 逆风的方向 更容易飞翔 世界怎样在于你凝视它的目光 那未曾谋面过的远方 或许就在身旁 &#x1f3b5…

洗地机哪个品牌好?四大实力拔尖单品力荐

洗地机哪个品牌好呢&#xff1f;想必姐妹们肯定觉得保持家里清洁是非常重要的&#xff0c;但是每天打扫卫生真的会让人整个都要疯狂&#xff0c;这不&#xff0c;救星洗地机就能派上用场了&#xff0c;干垃圾湿垃圾统统都能一次清理干净。只需轻轻一推&#xff0c;就能把扫地、…