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

伯克利Linux系统管理: 脚本编写学习 课堂与实验(系统简洁保姆级学习)

Linux系列文章目录

补充内容 Windows通过SSH连接Linux
第一章 Linux基本命令的学习与Linux历史
第二章(上) Vim课堂与实验


文章目录

  • Linux系列文章目录
  • 一、前言
  • 二、学习内容:
    • 2.1 上课内容
    • 2.1.1 为什么要学习脚本编写?
    • 2.1.2 Bash编程语言
    • 2.1.3 SheBang
    • 2.1.4 Shell的变量
    • 2.1.5 expr 命令算数运算
    • 2.1.6 read 命令用户输入
    • 2.1.7 test 命令条件判断
    • 2.1.8 bool、if与case 判断条件
    • 2.1.9 loops 循环
    • 2.1.10 动手试试
    • 2.1.11 function 方法
    • 2.1.12 stream 流操作
    • 2.1.13 推荐阅读
    • 2.2 实验内容
    • 2.2.1 一些让事情变得更简单的提示
    • 2.2.2 脚本参考
  • 三、问题描述
    • 3.1编写具有以下行为的 shell 脚本:phonebook
    • 3.2 骨架代码
      • 3.2.1 Bash的框架代码
      • 3.2.2 Python的框架代码
  • 四、解决方案:
    • 4.1 制作一个电话簿(Bash)
    • 4.2 制作一个电话簿(Python)
  • 五、总结:
    • 5.1 学习总结:

一、前言

原因:学校里没有开设相关课程但是学校其他课程与学习开发过程却需要用到相关知识,所以写此专栏以总结课程与实验内容
目的:记录学习过程内容做到条例清晰,通俗易懂,最好的学习方式是教会别人,以后忘记若复习能立即掌握(麻辣香蝈蝈)

  • 第二堂课本章拆成两节本节掌握Shell
  • 伯克利大学Linux系统管理大部分课程与实验内容都会涵盖
  • 题目为方便已翻译成中文,可在B站查找视频教程
  • 学习地址官网首页

二、学习内容:

在这里插入图片描述

2.1 上课内容

  • 上课主要讲的是Shell脚本编写
  • 为了方便可直接在命令行输入学习

2.1.1 为什么要学习脚本编写?

  • 需要频繁运行一些命令
  • 希望避免重复操作(DRY:Don’t Repeat Yourself)
  • 可以将任务描述为一系列步骤,让计算机执行

2.1.2 Bash编程语言

注:这些是他们公开课的ppt可去官网下载

  • Bash是一个shell,也是一种编程语言

在这里插入图片描述

运行Bash脚本的方法:

  • 使用bash /path/to/script命令(通常是.sh文件)
  • 使用chmod +x /path/to/script命令赋予脚本执行权限,然后运行/path/to/script
    使用shebang指定解释器(例如#!/bin/bash)

2.1.3 SheBang

  • Shebang(#!)是脚本文件的第一行,用于指定该脚本文件将使用的解释器。Shebang行以字符#!开头,后跟解释器的路径

在这里插入图片描述

Shebang的作用:

  • 指定解释器:告诉操作系统使用哪个解释器来运行脚本文件。
  • 提高可移植性:通过指定Shebang,可以确保在不同环境中运行脚本时使用正确的解释器。
  • 方便执行:无需在命令行中手动指定解释器,只需直接执行脚本文件即可。

使用Shebang的步骤:

  • 在脚本的第一行添加Shebang:例如#!/bin/bash。
  • 确保脚本具有执行权限:使用chmod +x script.sh命令赋予脚本执行权限。
  • 直接执行脚本:在命令行中输入./script.sh来执行脚本。

2.1.4 Shell的变量

  • Shell变量

在这里插入图片描述

  • 空格很重要!
  • echo:这是一个Shell命令,用于在终端输出文本。
  • $Name”:这是对变量的引用
  • 在变量名前加上$符号,可以获取变量的值。
  • 双引号确保变量在被输出时内容会被解析和显示

2.1.5 expr 命令算数运算

  • 使用 expr 命令进行算术运算

在这里插入图片描述

  • 变量没有类型(都是字符串)

2.1.6 read 命令用户输入

在这里插入图片描述

2.1.7 test 命令条件判断

  • 0是正确,1是错误

他的解释是运行失败后1是退出

在这里插入图片描述

  • 符号判断

在这里插入图片描述

记忆方法:

  • -eq(equal)
  • -ne(not equal)
  • -gt(greater than)
  • -ge(greater than or equal to)
  • -lt(less than)
  • -le(less than or equal to)

在这里插入图片描述

命令执行:

  • 当你在Shell中执行任何命令时,Shell会启动一个子进程来运行该命令。
  • 当子进程完成时,它会返回一个退出状态给父进程(即Shell)。

获取退出状态:

  • Shell会将最近一个命令的退出状态存储在特殊变量?中。
  • 通过引用 $?,你可以获取并使用这个退出状态。
  • $# 用于表示传递给 shell 脚本的参数数量。$# 将返回这些参数的数量。

进行错误处理和控制流:

  • 在脚本中使用$?来检查命令是否成功执行

变量引用概念

  • Shell:通过变量名直接修改值,没有指针的间接修改概念。例如,name="Bob"直接修改变量name的值。
  • 指针(如C语言):通过指针可以间接修改值。例如,*ptr = 100修改ptr指向的变量的值。

2.1.8 bool、if与case 判断条件

自己实验试试 if then 与 case in 判断

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 我们写的时候要保证[ ]方括号里面内容的间隔别出错

2.1.9 loops 循环

想想不同语言之间循环的区别

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.1.10 动手试试

课堂上的动手实验

运行 ./mycoolscript.sh 前要授权

chmod +x mycoolscript.sh

动手操作

在这里插入图片描述

这是在 .sh 脚本文件下的内容
这题对实验有帮助
可用vim打开

在这里插入图片描述

课上第一行写解释器路径的时候他能跳出选项
当时我不知道操作但在后来vim的实验中与作弊表中找到方法
详细可看上节课内容 Vim的使用与作弊表
我直接写出实现的方法

关键词补全方法

  • Ctrl + P

补全路径的方法

  • 使用 Vim 的内置补全机制。
  • Ctrl-X 然后按 Ctrl-F 可进行文件名补全
  • Ctrl-X 然后按 Ctrl-K 可进行关键词补全。

在这里插入图片描述

2.1.11 function 方法

解释:
在 Bash 脚本中,$1 是一个位置参数,它代表传递给脚本或函数的第一个参数。
类似的$2就是第二个

  • greet是函数名
  • 后面跟的则是参数

在这里插入图片描述

在这里插入图片描述

2.1.12 stream 流操作

对文件操作

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

管道

  • 别跟或混在一起
  • | 左边的输出是右边的输入
    在这里插入图片描述

2.1.13 推荐阅读

在这里插入图片描述

2.2 实验内容

上节学Vim
这节主要是Shell部分

  • Vim速查表

在这里插入图片描述
在这里插入图片描述

2.2.1 一些让事情变得更简单的提示

  1. bash有一个 append 运算符,正如您可能猜到的那样,它会附加 从第一个参数到第二个参数结束的数据。>>
$ cat foobar.txt
foobar
$ echo "hello, reader" >> foobar.txt
$ cat foobar.txt
foobar
hello, reader
  1. bash还有一个重定向算子,它接受一个的输出命令并将其输出到文件中。 >
$ cat foobar.txt
foobar
$ echo "hello" > foobar.txt
$ cat foobar.txt
hello
$ > foobar.txt
$ cat foobar.txt
$
  1. 只需写入文件和读取文件即可持久保存数据。

在 bash 中,可以通过命令更改行。
sed 是独立且强大的文本处理命令行工具
-i 选项使得 sed 会就地(in-place)编辑文件。

  • sed:流编辑器(Stream Editor),用于处理和转换文本数据
  • -i:直接修改文件内容,不会将结果输出到终端。

s/<old>/<new>/g”:这是 sed 的主要操作部分,表示进行替换操作。
具体的含义如下:

  • s:表示“替换”(substitute)。
  • <old>:旧字符串(被新字符串替代)。
  • <new>:新字符串。
  • g:表示全局替换,在每一行中找到所有出现的 字符串都进行替换,而不仅仅是替换每行中的第一个出现的实例。
  • ./filename:这是要进行编辑的目标文件的路径和文件名。./ 表示当前目录,后面跟着的 filename 代表文件名。

在这里插入图片描述

$ echo "hello 123" > foobar.txt # writes hello to foobar.txt
$ cat foobar.txt
hello 123
$ sed -i "s/h/j/g" foobar.txt
$ cat foobar.txt
jello 123
# You can also use regex: learn more at regex101.com
$ sed -i "s/[0-9]\{3\}/world/g" foobar.txt
$ cat foobar.txt
jello world
  • 通过位置参数公开了其命令行参数:bash $<Integer>
#!/bin/bash
# contents of argscript.shecho "$1"
echo "$2"
$ ./argscript.sh foo bar
foo
bar
  • 上面的命令用于执行这个脚本,foo 和 bar 是传递给脚本的参数。

对于引号原文给了复杂的定义说简单点就下面两点

  • 单引号:内容就是字面意思,适合你不想让内容变的情况。
  • 双引号:里面可以有变量,会自动插入变量的值。适合你需要动态内容的情况。
$ echo '$LANG'
$LANG
$ echo "$LANG"
en_US.UTF-8
  1. 您可以通过列表与命令行参数进行交互

这里是讲python相关的

在 Python 中,sys.argv 是一个列表,它包含了命令行参数。

  1. 您可以通过列表与命令行参数进行交互
  2. 命令行运行一个 Python 脚本时,你可以传递参数给这个脚本。
  3. 这些参数会被存储在 sys.argv 列表中。
  • 首先导入 sys 模块使用 sys.argv
  • sys.argv[0] 是脚本本身的名称。
  • sys.argv[1] 开始是传给脚本的第一个参数。
  • 可以根据需要继续使用 sys.argv[2], sys.argv[3] 等等。
# !/usr/bin/python
# contents of argscript.pyimport sys 
print(sys.argv[1]) 
print(sys.argv[2])
# end of file
$ ./argscript.py foo bar
foo
bar
  • python允许您使用常用的功能操作文件 具有控制结构

在这里插入图片描述

# !/usr/bin/python
# contents of fileman.pywith open('./newfile.txt', 'w') as f: f.write("hello from python\n")
# end of file
$ python fileman.py
$ cat newfile.txt
hello from python
  • 把phonebook.sh文件设置为可执行文件:
chmod +x phonebook.sh

2.2.2 脚本参考

几乎都是PPT的内容
可以进去写一写例题

链接地址:脚本参考


三、问题描述

  • 您将完成一个经典的第一个 shell 脚本任务:制作一个 电话簿。
  • 两种语言脚本区别

3.1编写具有以下行为的 shell 脚本:phonebook

  1. ./phonebook new <name> <number>将条目添加到电话簿中。不要担心重复(始终添加一个新条目,即使名称相同)。
  2. ./phonebook list显示电话簿中的每个条目(无特别说明) 订单)。如果电话簿没有条目,则显示phonebook is
    empty
  3. ./phonebook remove <name>删除与该名称关联的所有条目。如果该名称不在电话簿中,则不执行任何操作。
  4. ./phonebook clear删除整个电话簿
  5. ./phonebook lookup <name>显示与该名称关联的所有电话号码。您可以假设所有电话号码都采用以下形式:其中是 0-9
    之间的数字。ddd-ddd-ddddd

注意:您可以打印每行的名称和编号。对于额外的挑战,请尝试打印所有不带其姓名的电话号码。(有关详细信息,请参阅下面的示例)

$ ./phonebook new "Linus Torvalds" 101-110-0111
$ ./phonebook list
Linus Torvalds 101-110-1010
$ ./phonebook new "Tux Penguin" 555-666-7777
$ ./phonebook new "Linus Torvalds" 222-222-2222
$ ./phonebook list
Linus Torvalds 101-110-1010
Tux Penguin 555-666-7777
Linus Torvalds 222-222-2222
# OPTIONAL BEHAVIOR
$ ./phonebook lookup "Linus Torvalds" 
101-110-1010
222-222-2222
# ALTERNATIVE BEHAVIOR
$ ./phonebook lookup "Linus Torvalds"
Linus Torvalds 101-110-1010
Linus Torvalds 222-222-2222
$ ./phonebook remove "Linus Torvalds"
$ ./phonebook list
Tux Penguin 555-666-7777
$ ./phonebook clear
$ ./phonebook list
phonebook is empty

python的测试文本(选做)

# Add new entries
python phonebook.py new "Linus Torvalds" 101-110-0111
python phonebook.py new "Tux Penguin" 555-666-7777
python phonebook.py new "Linus Torvalds" 222-222-2222# List entries
python phonebook.py list# Lookup an entry
python phonebook.py lookup "Linus Torvalds"# Remove an entry
python phonebook.py remove "Linus Torvalds"# List entries to verify removal
python phonebook.py list# Clear the phonebook
python phonebook.py clear# List entries to verify clearing
python phonebook.py list

3.2 骨架代码

填充下面代码
完成上面 3.1 题目的要求

3.2.1 Bash的框架代码

#!/bin/bashPHONEBOOK_ENTRIES="bash_phonebook_entries"if [ "$#" -lt 1 ]; thenexit 1elif [ "$1" = "new" ]; then# YOUR CODE HERE #elif [ "$1" = "list" ]; thenif [ ! -e $PHONEBOOK_ENTRIES ] || [ ! -s $PHONEBOOK_ENTRIES ]; thenecho "phonebook is empty"else# YOUR CODE HERE #fielif [ "$1" = "lookup" ]; then# YOUR CODE HERE #elif [ "$1" = "remove" ]; then# YOUR CODE HERE #elif [ "$1" = "clear" ]; then# YOUR CODE HERE #else# YOUR CODE HERE #
fi

3.2.2 Python的框架代码

#!/usr/bin/env pythonimport sys
import osPHONEBOOK_ENTRIES = "python_phonebook_entries"def main():if len(sys.argv) < 2:exit(1)elif sys.argv[1] == "new":# YOUR CODE HERE #elif sys.argv[1] == "list":if not os.path.isfile(PHONEBOOK_ENTRIES) or os.path.getsize(PHONEBOOK_ENTRIES) == 0:print("phonebook is empty")else:# YOUR CODE HERE #elif sys.argv[1] == "lookup":# YOUR CODE HERE #elif sys.argv[1] == "remove":name = " ".join(sys.argv[2:])# YOUR CODE HERE #elif sys.argv[1] == "clear":# YOUR CODE HERE #else:name = " ".join(sys.argv[1:])with open(PHONEBOOK_ENTRIES, 'r') as f:lookup = "".join(filter(lambda line: name in line, f.readlines()))# YOUR CODE HERE #if __name__ == "__main__":main()

四、解决方案:

4.1 制作一个电话簿(Bash)

  1. 先自己写一点试一试

在这里插入图片描述

  • 要注意 [ ] 里面参数之间的空格
  • 要注意 Bash 脚本中的双引号

使用双引号原因如下

处理空格

  • 如果文件路径(在这里是变量 SAVE 的值)中含有空格,双引号的使用可以保证整个字符串被视为一个单一的参数。
  • 例如,如果 SAVE 的值为 “My Documents/SAVEPLACE”,没有双引号有可能导致错误解析。

防止扩展错误

  • 尤其是当变量为空或未定义时,使用双引号可以避免一些潜在的错误。

  • 如果没有双引号,脚本可能会尝试解析一个未定义的变量,导致意外的结果。

安全性

  • 双引号也能防止字元解释,比如 *、? 等通配符,确保它们不会被 Bash 解释为文件匹配。
SAVE="My Documents/SAVEPLACE"  
echo "$SAVE"   # 正确输出:My Documents/SAVEPLACE  
echo $SAVE     # 可能输出:My Documents/SAVEPLACE   这时会产生两个参数
  1. 参考代码

大部分参数都有解释
只解释没提到的
下面代码可以成功运行

#!/bin/bashPHONEBOOK_ENTRIES="bash_phonebook_entries"if [ "$#" -lt 1 ]; thenexit 1elif [ "$1" = "new" ]; thenif [ "$#" -ne 3 ]; thenecho "Usage: $0 new <name> <number>"exit 1fiecho "$2 $3" >> "$PHONEBOOK_ENTRIES"echo "Added: $2 $3"elif [ "$1" = "list" ]; thenif [ ! -e "$PHONEBOOK_ENTRIES" ] || [ ! -s "$PHONEBOOK_ENTRIES" ]; thenecho "phonebook is empty"elsecat "$PHONEBOOK_ENTRIES"fielif [ "$1" = "lookup" ]; thenif [ "$#" -ne 2 ]; thenecho "Usage: $0 lookup <name>"exit 1fiif grep -q "$2" "$PHONEBOOK_ENTRIES"; thengrep "$2" "$PHONEBOOK_ENTRIES" | awk '{print $2}'elseecho "No entry found for $2"fielif [ "$1" = "remove" ]; thenif [ "$#" -ne 2 ]; thenecho "Usage: $0 remove <name>"exit 1fiif grep -q "$2" "$PHONEBOOK_ENTRIES"; then# 取出内容放入temp后再通过mv覆盖原文件grep -v "$2" "$PHONEBOOK_ENTRIES" > temp && mv temp "$PHONEBOOK_ENTRIES" echo "Removed all entries for $2"elseecho "No entry found for $2"fi
elif [ "$1" = "clear" ]; then> "$PHONEBOOK_ENTRIES"echo "Phonebook cleared"elseecho "Usage: $0 {new|list|lookup|remove|clear}"exit 1
fi

! -e "$PHONEBOOK_ENTRIES" 和 ! -s "$PHONEBOOK_ENTRIES":

  • -e 是一个条件测试操作符,用于检查文件是否存在。
  • -s 是一个条件测试操作符,用于检查文件是否为空。

awk '{print $2}':

  • awk 是一个文本处理工具,用于对文本文件中的数据进行处理。
  • 在这里,它用于打印匹配行的第二个字段(假设字段以空格分隔)。
  • {print $2} 表示只打印每一行的第二个字段。

4.2 制作一个电话簿(Python)

此代码仅供参考

记得升级python版本

#!/usr/bin/env pythonimport sys
import osPHONEBOOK_ENTRIES = "python_phonebook_entries"def main():if len(sys.argv) < 2:print("Usage: <script> {new|list|lookup|remove|clear} [args]")exit(1)command = sys.argv[1]if command == "new":if len(sys.argv) != 4:print("Usage: <script> new <name> <number>")exit(1)name, number = sys.argv[2], sys.argv[3]with open(PHONEBOOK_ENTRIES, 'a') as f:f.write(f"{name} {number}\n")print(f"Added: {name} {number}")elif command == "list":if not os.path.isfile(PHONEBOOK_ENTRIES) or os.path.getsize(PHONEBOOK_ENTRIES) == 0:print("phonebook is empty")else:with open(PHONEBOOK_ENTRIES, 'r') as f:print(f.read(), end='')elif command == "lookup":if len(sys.argv) != 3:print("Usage: <script> lookup <name>")exit(1)name = sys.argv[2]found = Falsewith open(PHONEBOOK_ENTRIES, 'r') as f:for line in f:entry_name, entry_number = line.strip().split(maxsplit=1)if entry_name == name:print(entry_number)found = Trueif not found:print(f"No entry found for {name}")elif command == "remove":if len(sys.argv) != 3:print("Usage: <script> remove <name>")exit(1)name = sys.argv[2]found = Falsewith open(PHONEBOOK_ENTRIES, 'r') as f:lines = f.readlines()with open(PHONEBOOK_ENTRIES, 'w') as f:for line in lines:if name not in line.split(maxsplit=1)[0]:f.write(line)else:found = Trueif found:print(f"Removed all entries for {name}")else:print(f"No entry found for {name}")elif command == "clear":open(PHONEBOOK_ENTRIES, 'w').close()print("Phonebook cleared")else:print("Usage: <script> {new|list|lookup|remove|clear}")exit(1)if __name__ == "__main__":main()

五、总结:

5.1 学习总结:

主要是动手练习
Shebang:指定脚本使用的解释器,例如 #!/bin/bash。 运行脚本

bash /path/to/script
chmod +x /path/to/script ./path/to/script

变量

  • 定义变量:NAME=“value”
  • 输出变量:echo “$NAME”
  • 变量类型:Bash 中的变量是无类型的,一切皆为字符串。
  • 表达式求值:使用 expr 命令,例如 FOO=1 然后 expr $FOO + 1

操作符:

  • 等于:-eq
  • 不等于:-ne
  • 大于:-gt
  • 大于等于:-ge
  • 小于:-lt
  • 小于等于:-le
  • 布尔操作符:&&(与),||(或)

条件语句

  • if
 if [ "$1" -eq 79 ]; then echo "nice"fi
  • if-else
if [ "$1" -eq 79 ];thenecho "nice"
elseecho "darn"
fi
  • elif:用于多条件判断
  • case:用于多分支选择

循环
记住do done

  • for 循环:

基本形式:for ITEM in $ITEMS; do …; done
支持范围:for x in {1…10}; do …; done

  • while 循环:

while true; do …; done

函数

  • 定义函数:function greet() { echo “hey there $1”; }
  • 调用函数:例如 greet “sysadmin decal”

重定向和管道

  • 输出重定向:echo “hello” > out.txt
  • 追加输出:echo “hello” >> out.txt
  • 输入重定向:sort < file
  • 管道:command1 | command2

其他重要工具

  • Python:用于更复杂的控制结构或需要高级功能的任务。
  • argparse:简易 CLI
  • fabric:简易部署
  • salt:基础设施相关任务
  • psutil:监控系统信息
  • 其他 shell:例如 zsh、fish、ksh 等,每种 shell 可能有些许语法差异。

不同语言脚本的差异

  • 语法差异:Bash 使用简单的命令行语法和工具组合,Python 使用更结构化和面向对象的编程语法。
  • 功能和库:Bash 主要用于系统操作和自动化任务,Python 提供了丰富的库和模块用于各种编程任务。
  • 执行环境:Bash 通常在 Unix/Linux 环境下运行,Python 可以跨平台运行。

声明:如本内容中存在错误或不准确之处,欢迎指正。转载时请注明原作者信息(麻辣香蝈蝈)。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Python爬虫技术 第32节 最佳实践和常见问题
  • 函数指针数组
  • Spring快速学习
  • 基于Python的脑电图(EEG)信号分析(4)
  • 《程序猿入职必会(9) · 用代码生成器快速开发》
  • 【JavaScript】详解数组方法 fill()
  • 【已解决】VSCode连接Linux云服务器,代码写着写着服务器突然挂了是怎么回事?
  • 【爬虫实战】利用代理爬取电商数据
  • 【Python】Django Web 框架
  • STM32Cubemxide使用freertos的消息队列(QUEUE)
  • xss漏洞(五,xss-labs靶场搭建及简单讲解)
  • 03 LVS+Keepalived群集
  • Windows应急响应-排查方式
  • C++ 中基本数据类型所占字节简单说明
  • IsaacLab | Workflow 中 rsl_rl 的 play.py 脚本精读
  • 4月23日世界读书日 网络营销论坛推荐《正在爆发的营销革命》
  • 78. Subsets
  • golang中接口赋值与方法集
  • JavaScript 是如何工作的:WebRTC 和对等网络的机制!
  • Promise初体验
  • Sublime text 3 3103 注册码
  • 理解在java “”i=i++;”所发生的事情
  • 小程序、APP Store 需要的 SSL 证书是个什么东西?
  • 再次简单明了总结flex布局,一看就懂...
  • 东超科技获得千万级Pre-A轮融资,投资方为中科创星 ...
  • 容器镜像
  • 树莓派用上kodexplorer也能玩成私有网盘
  • ​TypeScript都不会用,也敢说会前端?
  • ​十个常见的 Python 脚本 (详细介绍 + 代码举例)
  • ​虚拟化系列介绍(十)
  • # 安徽锐锋科技IDMS系统简介
  • #我与Java虚拟机的故事#连载19:等我技术变强了,我会去看你的 ​
  • $NOIp2018$劝退记
  • (16)Reactor的测试——响应式Spring的道法术器
  • (2024.6.23)最新版MAVEN的安装和配置教程(超详细)
  • (7)摄像机和云台
  • (超简单)构建高可用网络应用:使用Nginx进行负载均衡与健康检查
  • (回溯) LeetCode 77. 组合
  • (教学思路 C#之类三)方法参数类型(ref、out、parmas)
  • (十)【Jmeter】线程(Threads(Users))之jp@gc - Stepping Thread Group (deprecated)
  • *++p:p先自+,然后*p,最终为3 ++*p:先*p,即arr[0]=1,然后再++,最终为2 *p++:值为arr[0],即1,该语句执行完毕后,p指向arr[1]
  • ./include/caffe/util/cudnn.hpp: In function ‘const char* cudnnGetErrorString(cudnnStatus_t)’: ./incl
  • .net core 3.0 linux,.NET Core 3.0 的新增功能
  • .NET Core跨平台微服务学习资源
  • .NET 项目中发送电子邮件异步处理和错误机制的解决方案
  • .net程序集学习心得
  • .NET轻量级ORM组件Dapper葵花宝典
  • .net实现客户区延伸至至非客户区
  • @德人合科技——天锐绿盾 | 图纸加密软件有哪些功能呢?
  • [2010-8-30]
  • [20180312]进程管理其中的SQL Server进程占用内存远远大于SQL server内部统计出来的内存...
  • [AI Embedchain] 开始使用 - 全栈
  • [Algorithm][综合训练][体育课测验(二)][合唱队形][宵暗的妖怪]详细讲解
  • [AMQP Connection 127.0.0.1:5672] An unexpected connection driver error occured
  • [BZOJ 4129]Haruna’s Breakfast(树上带修改莫队)