shell脚本基础语法(.sh ./ sh bash source shell)

Linux 之 Shell 脚本基础语法

0. 学习一门语言的顺序

1. Shell 编程概述

1.1 Shell 名词解释

在 Linux 操作系统中,Shell 是一个命令行解释器,它为用户提供了一个与操作系统内核交互的界面。用户可以通过 Shell 输入命令,然后 Shell 将这些命令翻译给操作系统去执行。Shell 还可以用来编写脚本,自动化执行重复的任务。

  • kernel:Linux 的内容,主要是为了和硬件打交道。
  • Shell:
    • 命令解释器(command interpreter)
    • Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。
    • Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。

Shell 目前有两大主流:

  1. sh:
    1. Bourne Shell (sh): Solaris, hpux 默认的 Shell
    2. Bourne again shll (bash):Linux 系统默认的 Shell
  2. csh:
    1. C shell (csh)
    2. tc shell (tcsh)

⚠️ 我们在使用 shell 脚本时需要进行声明,使用 #!,从而告诉系统我们要使用哪个路径下的 shell 解释器,例子如下:

#!/bin/bash
echo "Hello World!"

Question#!/bin/sh#!/bin/bash 有区别吗?

Answer#!/bin/sh#!/bin/bash 的区别主要在于它们指定了不同的 shell 解释器。

  • #! /bin/sh 是一个较老的用法,它指定脚本应该由 Bourne shell(或者兼容 Bourne shell 的 shell)来执行。在大多数现代 Linux 系统中,/bin/sh 已经是 bash(Bourne-Again SHell)的一个符号链接或者是一个兼容 shell 的链接,因为 bash 兼容并扩展了原始的 Bourne shell。所以,即使你使用 #!/bin/sh,实际执行的可能是 bash
    #!/bin/bash 则明确指定了脚本应该由 bash 来执行。这样做的好处是可以确保使用 bash 的特定扩展和特性。如果你在脚本中使用了 bash 的特定功能,那么你应该使用 #! /bin/bash 作为 shebang。

1.2 Shell 脚本的执行方式

1.2.1 输入脚本的绝对路径或相对路径

# 绝对路径
/mnt/f/Projects/本地代码/Learning-Notebook-Codes/Linux/shell/codes/hello_world.sh# 相对路径
Linux/shell/codes/hello_world.sh

⚠️ 该种执行方式下,.sh 文件必须是一个可执行文件,即拥有 x 权限

1.2.2 bash 或者 sh + 脚本路径

# 绝对路径
sh /mnt/f/Projects/本地代码/Learning-Notebook-Codes/Linux/shell/codes/hello_world.sh# 相对路径
sh Linux/shell/codes/hello_world.sh

⚠️ 当脚本没有 x 权限时,root 用户和文件所有者可以通过该方式正常执行

1.2.3 source + 脚本路径

# 绝对路径
source /mnt/f/Projects/本地代码/Learning-Notebook-Codes/Linux/shell/codes/hello_world.sh# 相对路径
source Linux/shell/codes/hello_world.sh

1.2.4 三种执行方式的对比

执行方式要求
绝对路径/相对路径必须是可执行文件
sh无(普通文件和脚本文件都可以)
source无(普通文件和脚本文件都可以)

不同点:我们举个例子,现在终端中输入下面的命令

uname = admin
echo $uname

之后修改 Linux/shell/codes/hello_world.sh 脚本:

#!/bin/bashecho "Hello World!"
echo $uname

我们再看一下三种方式的结果:

那么为什么前两种方式没有打印出来 uname 变量呢?

首先,我们需要了解这三种执行方式的区别:

  1. 绝对路径/相对路径:这种方式会开启一个子 Shell 来执行脚本。这意味着脚本将在一个全新的环境中运行,其中的变量和操作不会影响到父 Shell。
  2. sh:这种方式也是在一个新的 Shell 环境中执行脚本,与绝对路径/相对路径执行方式类似。
  3. source:这种方式会在当前 Shell 环境中执行脚本,而不是在一个新的子 Shell 中。因此,脚本中的任何更改(例如,设置或更改环境变量)都会影响到当前 Shell。

1.3 export 关键字

在 Shell 脚本中,export 关键字用来将脚本中的变量声明为环境变量,这意味着该变量可以被脚本中执行的任何命令或子 Shell 访问。环境变量对于定义和控制脚本的执行环境非常有用,例如,可以用来设置路径、定义配置选项或传递参数。

当你在 Shell 脚本中使用 export 时,你实际上是修改了当前 Shell 的环境。任何从这个 Shell 启动的子 Shell 或者进程都会继承这些环境变量。

下面是一个简单的例子:

#!/bin/bash
# 定义一个变量
my_variable="Hello, World! "# 输出变量,此时它仅存在于当前 Shell 中
echo $my_variable# 将变量导出为环境变量
export my_variable# 此时,启动一个子 Shell
bash -c 'echo $my_variable'

结果如下:

在上面的脚本中,my_variable 首先被定义并输出,然后通过 export 导出。在启动的子 Shell 中,我们同样可以访问 my_variable,这是因为 export 使得该变量成为了环境变量。

需要注意的是,默认情况下,在函数内部设置的变量是不会自动成为环境变量的,如果需要在函数外部访问函数内部设置的变量,也需要使用 export 来导出这些变量。

⚠️ 这个环境变量只是在当前终端生效,如果我们在 A 终端使用了 export,但在新开启的终端 B 中是不生效的,如下所示:

这是因为每个终端会话(session)通常都有自己的独立环境。当我们打开一个新的终端时,它会从系统环境中继承一系列默认的环境变量,但不会继承其他终端会话中通过 export 设置的变量。

💡 如果我们希望环境变量在新的终端会话中自动生效,我们可以将 export 命令添加到我们的 Shell 启动文件中,例如 ~/.bashrc~/.bash_profile~/.profile,这取决于我们使用的 Shell 和配置。这样,每次启动新的 Shell 时,这些文件都会被读取,从而设置相应的环境变量。

1.4 cat 关键字

在 Shell 中,cat(全称“concatenate”)是一个常用的命令行工具,用于查看文件内容、创建文件、文件合并以及将文件内容重定向到另一个文件等操作。

1.4.1 查看文件内容

假设 A.txt 文件中的内容如下:

这是A文件

那我们可以直接在 Shell 中查看它:

cat cat Linux/shell/assets/A.txt

结果如下:

Question:我们会发现并没有换行,这是为什么呢?

Answer:这是因为我们的 A.txt 文件的内容确实以 这是A文件 结尾,并且后面没有换行符,那么 cat 命令的输出中也就不会显示换行。在文本文件中,换行符通常是一个特殊的字符,它告诉文本编辑器或命令行界面在新的一行开始。如果文件最后一行没有换行符,那么命令提示符就会直接跟在文件内容的后面,看起来就像是没有换行一样。

那我们在 A.txt 文件后面添加一行呢?即 A.txt 文件内容如下:

这是A文件

结果如下:

正常换行了,那我们还有其他方法吗?比如我们在 A.txt 文件的末尾加上一个换行符:

这是A文件\n

我们再看一下效果:

⚠️ 并没有换行!这是因为我们在 A.txt 文件的末尾添加一个文本字符串 "\n"这并不会在文件中添加一个真正的换行符"\n" 只是一个由两个字符组成的普通字符串:反斜杠 (\) 和字母 n

💡 如果要创建一个真正的换行符,我们需要在文本编辑器中实际按下 Enter 键,或者在命令行中使用转义序列。

在命令行中,我们可以使用 echo 命令的 -e 选项来解释转义序列。下面是如何在 A.txt 文件末尾添加一个真正的换行符:

echo -e "这是A文件\n" >> Linux/shell/assets/A.txt

这个命令会在 A.txt 文件中追加文本 这是A文件 后跟一个真正的换行符。

如果我们想在不使用 -e 选项的情况下添加换行符,可以在 A.txt 文件中直接按 Enter 键,或者在命令行中使用 printf 命令:

printf "这是A文件\n" >> Linux/shell/assets/A.txt

printf 命令默认就会解释转义序列,所以不需要额外的选项来添加换行符。

⚠️ 注意,如果我们直接在文本编辑器中编辑文件并保存,通常编辑器会在文件的末尾自动添加一个换行符,除非我们明确地删除了它。

1.4.2 创建新文件或编辑现有文件

# cat > filename
cat > Linux/shell/assets/A.txt

此时我们可以输入我们想输入的内容,在按下 Ctrl+D 保存并退出。

由于我们没有敲回车,所以 (base) root@Le0v1n... 这些内容在我们输入的内容之后。如果我们想要换行的效果,可以在输入内容的之后手动敲回车,如下所示:

⚠️ 如果文件已存在,这将清空文件内容

Questioncat > filename 只能清空所有内容并编写吗?可以追加内容吗?

Answer:当然是可以的了,往下看。

1.4.3 将文件内容追加到另一个文件的末尾

cat file1 >> file2

这会将file1的内容追加到file2的末尾,而不是覆盖它。

举个例子:

cat >> Linux/shell/assets/A.txt

💡 总结一下

  • cat > filename:清空文件内容并重新编写。
  • cat >> filename:追加内容到文件的末尾。

1.4.4 将多个文件的内容合并输出

cat file1 file2 file3

这将依次显示 file1file2file3 的内容。

我们实际试一下:

cat Linux/shell/assets/A.txt Linux/shell/assets/B.txt Linux/shell/assets/C.txt

1.4.5 将文件内容重定向(redirection)到另一个文件

cat file1 > file2

这会将 file1 的内容覆盖到 file2 中。如果 file2 不存在,则创建它。

例子:

cat Linux/shell/assets/A.txt > Linux/shell/assets/exp-redirection.txt

💡 如果我们想让 file1 的内容追加到 file2 的末尾,使用 cat file1 >> file2 也是可以的!

1.4.6 显示文件内容并显示行号

cat -n filename

试一下:

cat -n Linux/shell/assets/A.txt

1.4.7 总结

# 1. 查看文件内容
cat filename# 2. 创建新文件或编辑现有文件(使用 ctrl+D 保存)
cat > filename# 3. 将文件内容追加到另一个文件的末尾
cat >> filename# 4. 将多个文件的内容合并输出
cat file1 file2 file3# 5. 将文件内容重定向(redirection)到另一个文件
cat file1 > file2# 6. 显示文件内容并显示行号
cat -n filename

⚠️ cat 命令在处理小文件或查看文件内容时非常有用,但它不适合处理非常大的文件,因为cat会一次性将整个文件加载到内存中,这可能会导致内存不足的问题。

💡 对于大文件,可以使用其他命令如lessmore,这些命令可以分页显示文件内容,避免内存问题。

2. Shell 基础入门

2.1 shell 变量

2.1.1 变量命名

定义变量时,变量名不加美元符号 $,且有一些命名规则:

  • 命名只能使用英文字母、数字和下划线(_),且首个字符必须是非数字的字母
  • 中间不能有空格,但可以使用下划线 _ 作为单词分隔符
  • 不能使用标点符号,如 !, @, #, $, %, ^, &, *, (, ), -, =, +, [, ], {, }, |, :, ;, ', ", <, >, ,, ., /, ?
  • 不能使用 bash 里的关键字,如 if, for, while, function

⚠️ 不推荐使用 -,因为它在某些情况下可能会导致语法错误或被解释为命令行选项。在变量替换时,如果变量名包含 -,建议将变量名用大括号 {} 包起来,例如 ${var-value}

2.1.2 变量类型

  • 局部变量:在脚本或命令中定义,仅在当前 shell 实例中有效,其他 shell 启动的程序不能访问局部变量。
  • 环境变量:任何由当前 shell 启动的程序都可以访问环境变量。环境变量对于程序的配置和运行非常重要。
  • shell 变量:由 shell 程序设置的特殊变量,包括环境变量和局部变量。Shell 变量通常用于存储 shell 的状态信息或作为脚本编程的辅助工具。

2.1.3 补充说明

  • 对于环境变量,可以使用 export 命令将局部变量提升为环境变量,使得它对当前 shell 及其所有子进程可见。
  • ⚠️ 变量赋值时,等号 = 两边不能直接接空格。
  • 为了避免潜在的问题,建议在脚本中使用明确的变量名,避免使用可能具有特殊含义的字符。

2.1.4 示例

#!/bin/bash# 定义变量
name="Le0v1n"# 变量的调用
echo $name
echo ${name}
Le0v1n
Le0v1n

💡 使用花括号 {} 来包围变量名在某些情况下是必要的,比如变量名后面紧跟着其他字符时,或者变量名是一个复杂表达式的一部分时,它可以避免语法歧义,确保Bash正确地解析变量名。

2.2 Shell 的字符串

2.2.1 定义

字符串是 Shell 编程中最常用也是最有用的数据类型之一。在 Shell 中,字符串可以使用单引号,也可以使用双引号,而且确实在某些情况下可以不使用引号。

2.2.2 单双引号

下面是关于单引号和双引号的详细说明:

  • 单引号

    • 单引号里的任何字符都会原样输出,不会进行变量替换或特殊字符的转义。
    • 单引号字符串中的变量是无效的,即它们不会被替换为变量的值。
    • 单引号字符串中不能直接出现单独一个的单引号,但可以通过成对出现的方式包含单引号,例如 'I\'m a string'
  • 双引号

    • 双引号里可以有变量,Shell 会将变量的值替换到字符串中。
    • 双引号里可以出现转义字符,例如 "\n" 会被转义为换行符。

关于不使用引号的情况,Shell 解释器会根据一些规则来解释未加引号的字符串。通常,未加引号的字符串会被视为命令的参数,并且可能会发生单词分割和文件名扩展。这意味着如果字符串中包含空格或特殊字符,Shell 可能会错误地解释它们。因此,尽管在某些简单的情况下可以省略引号,但为了确保字符串的正确解析,通常建议使用单引号或双引号来定义字符串

2.2.3 单双引号的示例

#!/bin/bashstr1="hello world 1"  # 双引号
str2='hello world 2'  # 单引号# 直接调用
echo $str1  # hello world 1
echo $str2  # hello world 2
#!/bin/bash# 字符串拼接:双引号
name='le0v1n'
name1="hello, $name!"    # 双引号可以转义
name2="hello, "$name"!"  # "hello, "是成对的,"!"是成对的,所以$name不受影响
name3="hello, '$name'!"  # "hello, '$name'!"是成对的,且双引号可以转义
name4="hello, ${name}!"  # "hello, ${name}!"是成对的,且双引号可以转义echo $name1  # hello, le0v1n!
echo $name2  # hello, le0v1n!
echo $name3  # hello, 'le0v1n'!
echo $name4  # hello, le0v1n!
#!/bin/bash# 字符串拼接:单引号
name='le0v1n'name1='hello, $name!'    # 'hello, $name!'是成对的,但单引号不能转义
name2='hello, '$name'!'  # 'hello, '是成对的,'!'是成对的,所有$name不受影响
name3='hello, "$name"!'  # 'hello, "$name"!'是成对的,但单引号不能转义
name4='hello, ${name}!'  # 'hello, ${name}!'是成对的,但单引号不能转义echo $name1  # hello, $name!
echo $name2  # hello, le0v1n!
echo $name3  # hello, "$name"!
echo $name4  # hello, ${name}!

2.2.4 获取字符串长度和字符串切片

#!/bin/bash# 字符串长度
email="Le0v1n@163.com"echo ${email}      # Le0v1n@163.com
echo ${#email}     # 14
echo ${email:0:5}  # Le0v1

⚠️ 在运行该脚本的时候,要使用 bash 或者 ./ 或者 source,不要使用 sh

2.3 Shell 数组

2.3.1 定义

Shell 数组在 Bash 中是一个强大的特性,它允许我们存储多个值在单个变量中。数组在 Bash 中以索引方式访问,这使得它们在处理序列时非常有用。

  • bash 支持一维数组(不支持多维数组),并且没有限定数组的大小
  • 数组元素的索引从 0 开始。获取数组中的元素要使用索引,索引可以是整数或算术表达式,其值应该 ≥ 0

2.3.2 数组的创建

Shell 数组的定义:括号用来表示数组,数组元素用空格符号分隔开。

数组名=(value1 value2 ... valueN)

2.3.3 数组的索引

#!/bin/bash# 创建一个shell数组
exp_array=( "Hello" "world" "你好" '单引号')echo "数组为: ${exp_array}"     # 默认输出第一个元素
echo "数组为: ${exp_array[0]}"  # 按索引来
echo "数组为: ${exp_array[1]}" 
echo "数组为: ${exp_array[2]}"
echo "数组为: ${exp_array[3]}"
echo "数组为: ${exp_array[4]}"  # 越界的直接打印空
数组为: Hello
数组为: Hello
数组为: world
数组为: 你好
数组为: 单引号
数组为: 

2.3.4 取出所有元素

#!/bin/bashexp_array=( "Hello" "world" "你好" '单引号')# 使用 @ 符号可以取出数组中所有元素
echo ${exp_array[@]}
Hello world 你好 单引号

2.3.5 获取数组的长度

#!/bin/bash# 获取数组的长度
array_len_1=${#exp_array[@]}
array_len_2=${#exp_array[*]}echo $array_len_1
echo ${array_len_2}
4
4

⚠️ 注意:${#exp_array[@]}${#exp_array[*]} 都可以用来获取数组的长度,它们都会输出数组的长度。${#exp_array[@]} 适用于只提供数组名称的情况,而 ${#exp_array[*]} 适用于提供数组元素列表的情况下。

2.3.6 获取数组中某一个元素的长度

#!/bin/bashexp_array=( "Hello" "world" "你好" '单引号')# 获取数组中某一个元素的长度
elem_len_0=${#exp_array[0]}
elem_len_1=${#exp_array[1]}
elem_len_2=${#exp_array[2]}
elem_len_3=${#exp_array[3]}
elem_len_4=${#exp_array[4]}
echo ${elem_len_0}  # 5
echo ${elem_len_1}  # 5
echo ${elem_len_2}  # 2
echo ${elem_len_3}  # 3
echo ${elem_len_4}  # 0

⚠️ 注意:数组索引是从 0 开始的,所以 ${exp_array[4]} 是无效的,因为它超出了数组的范围。在尝试访问数组元素时,确保索引在数组范围内。

2.4 Shell 的注释

在 Shell 脚本中,注释用于解释代码,帮助其他开发者理解脚本的功能,或者在脚本中暂时禁用某些代码行。Shell 脚本中的注释有以下几种方式:

2.4.1 单行注释

使用 # 符号开始一个单行注释。# 符号后面的内容直到行尾都会被解释器忽略。

# 这是一个单行注释

2.4.2 多行注释(块注释)

虽然 Shell 没有专门的多行注释语法,但是你可以使用 # 符号来开始一个多行注释块。这种注释块会一直持续到遇到另一个 # 符号。

# 这是一个多行注释的开始
# 你可以在这里写很多行注释
# 直到再次遇到 #
# ----------------------------------------------
# 这也是一个多行注释
# 这也是一个多行注释
# 这也是一个多行注释
# 这也是一个多行注释
# 这也是一个多行注释
# ----------------------------------------------##### 服务器配置-start #####
# comment
# comment
# comment
# comment
# comment
##### 服务器配置-end   #####

2.4.3 Here Document(文档字符串)

Here Document 是一种特殊类型的注释,它可以用于将输入传递给命令。虽然它主要用于输入,但也可以用于创建注释块。

cat <<'EOF'
# 这是一个多行注释的开始
# 你可以在这里写很多行注释
# 直到再次遇到 #
EOF

在编写 Shell 脚本时,建议合理使用注释,以提高代码的可读性和可维护性。注释应该清晰、简洁,并且与代码保持一致。

2.5 Shell 脚本传参

在 Shell 脚本中,参数传递是脚本与调用脚本的环境之间交互的一种方式。参数可以是一系列值,传递给脚本以便脚本在执行时可以使用这些值。

2.5.1 参数传递机制

Shell 脚本可以通过命令行从外部接收参数。这些参数可以在脚本内部通过 $1$2$3 等特殊变量来访问。这些特殊变量被称为位置参数,它们按顺序存储了传递给脚本的参数值。

2.5.2 位置参数

特殊变量说明
$0脚本的名称
$1第一个参数
$2第二个参数
$3第三个参数
$n第 n 个参数

2.5.3 获取所有参数

可以使用 $@$* 特殊变量来获取所有传递给脚本的参数。

  • $@:表示所有位置参数的列表,每个参数都作为单独的单词处理。
  • $*:与 $@ 类似,但它将所有参数视为一个单词。

2.5.4 获取参数个数

可以使用 $# 特殊变量来获取传递给脚本的所有参数的个数。

2.5.5 示例

下面是一个简单的 Shell 脚本示例,展示了如何接收和处理参数。

#!/bin/bash# 打印脚本名称
echo "脚本名称: $0"# 打印所有参数
echo "所有参数: $@"# 打印参数个数
echo "参数个数: $#"# 打印第一个参数
echo "第一个参数: $1"# 打印第二个参数
echo "第二个参数: $2"# 打印第三个参数
echo "第三个参数: $3"

要运行这个脚本并传递参数,可以使用以下命令:

./script_name.sh 参数1 参数2 参数3

2.5.6 特殊参数

除了位置参数之外,还有一些特殊的参数,它们以 $ 符号开始,例如:

  • $*$@:用于引用所有位置参数。
  • $#:传递给脚本的所有参数的个数。
  • $?:最后一次命令的退出状态。
  • $$:当前 Shell 进程 ID(PID)。

这些特殊参数在脚本编程中非常有用,尤其是在需要与脚本调用者交互或处理命令行输入时。

2.5.7 示例:脚本使用特殊参数

下面是一个使用特殊参数的示例脚本:

#!/bin/bash# 打印所有参数,使用 $* 和 $@
echo "所有参数: $*"
echo "所有参数: $@"# 打印参数个数
echo "参数个数: $#"# 打印上一个命令的退出状态
echo "上一个命令的退出状态: $?"# 打印当前 Shell 的进程 ID
echo "当前 Shell 的进程 ID: $$"

这个脚本演示了如何使用特殊参数来获取关于脚本参数和执行环境的各种信息。

参考

  1. 这可能是B站讲的最好的Linux Shell脚本教程,3h打通Linux-shell全套教程,从入门到精通完整版

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

gcore服务器设置root账号密码登录

这个厂商很奇怪&#xff0c;默认只能用centos用户与公钥登录&#xff0c;但是这样有时候很麻烦。 他默认开启了SELinux&#xff0c;和强制ssh密钥登录。 下面所有操作在root模式下进行 SELinux设置为兼容模式 setenforce 0vi /etc/selinux/config然后将文件中的SELINUXenfo…

Doris中的本地routineload环境,用于开发回归测试用例

----------------2024-2-6-更新-------------- doris的routineload&#xff0c;就是从kafka中加载数据到表&#xff0c;特点是定时、周期性的从kafka取数据。 要想在本地开发测试routine load相关功能&#xff0c;需要配置kafka环境&#xff0c;尤其是需要增加routine load回…

CodeFuse-VLM 开源,支持多模态多任务预训练/微调

CodeFuse-MFT-VLM 项目地址&#xff1a;https://github.com/codefuse-ai/CodeFuse-MFT-VLM CodeFuse-VLM-14B 模型地址&#xff1a;CodeFuse-VLM-14B CodeFuse-VLM框架简介 随着huggingface开源社区的不断更新&#xff0c;会有更多的vision encoder 和 LLM 底座发布&#x…

I.MX6u嵌入式linux驱动开发

1&#xff1a;Ubuntu 系统入门 当 Ubuntu 系统入门以后&#xff0c;我们重点要学的就是如何在 Linux 下进行 C 语言开发&#xff0c;如何使 用 gcc 编译器、如何编写 Makefile 文件等等 首先安装虚拟机软件VM&#xff1a; Vmware Workstation 软件可以在 Wmeare …

如何使用Python + 百度翻译API 自动大批量免费翻译Excel文件中的外语内容

手里有一个Excel文件,包括了大量的亚马逊德语搜索词(关键词),每个单元格1个,需要翻译为中文。但是文件大小超过了10M,不能使用百度或Google免费的文档功能,如果手工一个个的翻译然后粘贴又太麻烦,于是想到用Python加免费翻译API完成。 一、openpyxl库 用Python编辑处…

洛谷_P1464 Function_python写法

目录 1.错误解法 2.学习记忆化搜索算法 2.1简介 2.2案例学习 3.解法 4.总结 1.错误解法 a 0 b 0 c 0 def w(a,b,c):if a<0 or b<0 or c<0:return 1elif a>20 or b>20 or c>20:return w(20,20,20)elif a<b and b<c:return w(a-1,b,c) w(a-1,…

1、将 ChatGPT 集成到数据科学工作流程中:提示和最佳实践

将 ChatGPT 集成到数据科学工作流程中:提示和最佳实践 希望将 ChatGPT 集成到您的数据科学工作流程中吗?这是一个利用 ChatGPT 进行数据科学的提示的实践。 ChatGPT、其继任者 GPT-4 及其开源替代品非常成功。开发人员和数据科学家都希望提高工作效率,并使用 ChatGPT 来简…

LRU缓存

有人从网络读数据&#xff0c;有人从磁盘读数据&#xff0c;机智的人懂得合理利用缓存加速数据的读取效率&#xff0c;提升程序的性能&#xff0c;搏得上司的赏识&#xff0c;赢得白富美的青睐&#xff0c;进一步走向人生巅峰~ LRU假说 LRU缓存&#xff08;Least Recently Used…

2023 巅峰之作 | AIGC、AGI、GhatGPT、人工智能大语言模型的崛起与挑战

文章目录 01 《ChatGPT 驱动软件开发》内容简介 02 《ChatGPT原理与实战》内容简介 03 《神经网络与深度学习》04 《AIGC重塑教育》内容简介 05 《通用人工智能》目  录 2023年是人工智能大语言模型大爆发的一年&#xff0c;一些概念和英文缩写也在这一年里集中出现&#xff…

12.0 Zookeeper 数据同步流程

在 Zookeeper 中&#xff0c;主要依赖 ZAB 协议来实现分布式数据一致性。 ZAB 协议分为两部分&#xff1a; 消息广播崩溃恢复 消息广播 Zookeeper 使用单一的主进程 Leader 来接收和处理客户端所有事务请求&#xff0c;并采用 ZAB 协议的原子广播协议&#xff0c;将事务请求…

10英寸安卓车载平板电脑丨ONERugged车载工业平板:解决农业工作效率

农业是人类社会的基石之一&#xff0c;而农业工作效率的提升一直是农民和农业专业人士关注的重要议题。随着技术的不断进步&#xff0c;车载工业平板成为了解决农业工作效率的创新解决方案。本文将探讨车载工业平板如何为农业带来巨大的改变&#xff0c;提高农民的工作效率和农…

JavaEE企业级应用软件开发—Spring框架入门学习笔记(一)

一、认识框架 实际开发中&#xff0c;随着业务的发展&#xff0c;软件系统变得越来越复杂&#xff0c;如果所有的软件都从底层功能开始开发&#xff0c;那将是一个漫长而繁琐的过程。此外&#xff0c;团队协作开发时&#xff0c;由于没有统一的调用规范&#xff0c;系统会出现大…

幻兽帕鲁怎么样?好玩? Mac版的玩《幻兽帕鲁》也很简单,只需三个步骤

幻兽帕鲁怎么样 幻兽帕鲁是一款集合了多种游戏元素的游戏&#xff0c;它巧妙地融合了《方舟:生存进化》的野外生存挑战、《荒野之息》的开放世界探索、《魔兽世界》的多元角色互动以及宝可梦的精灵捕捉与培养等经典游戏元素。游戏的核心系统是「帕鲁」捕获&#xff0c;你可以让…

MySQL-存储引擎

文章目录 1. MySQL的体系结构2. 存储引擎2.1 存储引擎概述2.2 存储引擎的类型及选择方案2.3 操作存储引擎2.4 InnoDB存储引擎2.4.1 逻辑存储结构2.4.2 架构2.4.2.1 内存结构2.4.2.2 磁盘结构2.4.2.3 后台线程 2.4.3 事务2.4.3.1 Undo Log&#xff08;原子性&#xff09;2.4.3.2…

C语言其他类型的数组

1.字符数组 概念&#xff1a;专门存放字符的数组&#xff0c;称为字符数组初始化与元素引用&#xff1a; char s1[5] {a, b, c, d, e}; // s1存放的是字符序列&#xff0c;非字符串 char s2[6] {a, b, c, d, e, \0}; // s2存放了一个字符串char s[6] {"abcde&q…

【证书管理】实验报告

证书管理实验 【实验环境】 ISES客户端 【实验步骤】 查看证书 查看证书详细信息 选择任意证书状态&#xff0c;在下方“证书列表”中出现符合要求的所有证书。在“证书列表”中点击要查看证书&#xff0c;在右侧“证书详细信息”栏出现被选证书信息。 上述操作如图1.2.…

Maven详细配置整理

Maven的作用 在Javaweb开发中&#xff0c;需要使用大量的jar包&#xff0c;需要手动去导入&#xff0c;Maven能够自动帮我们导入和配置这个jar包。 对于新手Maven就是用来方便导入jar包的&#xff01; Maven的核心思想&#xff1a;约定大于配置 有约束&#xff0c;不要去违…

Jmeter 01 -概述线程组

1、Jmeter:概述 1.1 是什么&#xff1f; Jmeter是Apache公司使用Java 开发的一款测试工具 1.2 为什么&#xff1f; 高效、功能强大 模拟一些高并发或多次循环等特殊场景 1.3 怎么用&#xff1f; 下载安装 1、下载jmeter&#xff0c;解压缩2、安装Java环境&#xff08;jmet…

力扣53. 最大子数组和(滑动窗口,动态规划)

Problem: 53. 最大子数组和 文章目录 题目描述思路及解法复杂度Code 题目描述 思路及解法 思路1:滑动窗口 1.为求出最大连续的子数组和,我们逻辑上假设有一个窗口在原数组上滑动, 欲求出最大连续,则需要保证窗口中的所有元素和最起码大于0; 2.即当当前窗口中的元素值的和小于0…

从零开始手写mmo游戏从框架到爆炸(六)— 消息处理工厂

就好像门牌号一样&#xff0c;我们需要把消息路由到对应的楼栋和楼层&#xff0c;总不能像菜鸟一样让大家都来自己找数据吧。 首先这里我们参考了rabbitmq中的topic与tag模型&#xff0c;topic对应类&#xff0c;tag对应方法。 新增一个模块&#xff0c;专门记录路由eternity-…