自动化编写备忘录

news/2025/2/15 15:17:01/文章来源:https://www.cnblogs.com/mugetsukun/p/18713046

print()函数

1. Shell 中的 echoprintf

在 Shell 中,没有直接的 print() 函数,但可以使用 echoprintf 来实现类似功能。

echo

  • 用途:输出字符串或变量内容。
  • 语法
    echo "Hello, World!"
    
  • 特点
    • 自动在输出末尾添加换行符。
    • 支持变量替换。
    name="Alice"
    echo "Hello, $name!"
    
  • 禁用换行符
    echo -n "Hello, World!"
    

printf

  • 用途:格式化输出。
  • 语法
    printf "Hello, %s!\n" "World"
    
  • 特点
    • 支持格式化字符串(如 %s%d)。
    • 不会自动添加换行符,需要显式使用 \n

2. Python 中的 print()

在 Python 中,print() 是一个内置函数,用于将内容输出到控制台。

基本用法

  • 语法
    print("Hello, World!")
    
  • 特点
    • 自动在输出末尾添加换行符。
    • 支持多参数,默认用空格分隔。
    print("Hello", "World", "!")
    

格式化输出

  • 使用 f-string(推荐)
    name = "Alice"
    print(f"Hello, {name}!")
    
  • 使用 format() 方法
    name = "Alice"
    print("Hello, {}!".format(name))
    
  • 使用 % 格式化
    name = "Alice"
    print("Hello, %s!" % name)
    

控制换行

  • 禁用换行符
    print("Hello, World!", end="")
    

3. Golang 中的 fmt.Println()fmt.Printf()

在 Golang 中,print() 功能通过 fmt 包实现,主要有 fmt.Println()fmt.Printf()

fmt.Println()

  • 用途:输出内容并自动添加换行符。
  • 语法
    fmt.Println("Hello, World!")
    
  • 特点
    • 支持多参数,默认用空格分隔。
    fmt.Println("Hello", "World", "!")
    

fmt.Printf()

  • 用途:格式化输出。
  • 语法
    name := "Alice"
    fmt.Printf("Hello, %s!\n", name)
    
  • 特点
    • 支持格式化字符串(如 %s%d)。
    • 不会自动添加换行符,需要显式使用 \n

fmt.Print()

  • 用途:输出内容,不添加换行符。
  • 语法
    fmt.Print("Hello, World!")
    

对比总结

特性 Shell (echo) Python (print()) Golang (fmt.Println())
基本输出 echo "Hello, World!" print("Hello, World!") fmt.Println("Hello, World!")
格式化输出 printf f-string/format() fmt.Printf()
多参数支持 支持 支持 支持
自动换行 echo 自动换行 print() 自动换行 fmt.Println() 自动换行
禁用换行 echo -n print(..., end="") fmt.Print()

示例代码

Shell

echo "Hello, World!"
printf "Hello, %s!\n" "World"

Python

print("Hello, World!")
name = "Alice"
print(f"Hello, {name}!")

Golang

package main
import "fmt"
func main() {fmt.Println("Hello, World!")name := "Alice"fmt.Printf("Hello, %s!\n", name)
}

input()函数

1. Shell 中的 read

在 Shell 中,使用 read 命令获取用户输入。

基本用法

  • 语法
    read -p "Enter your name: " name
    echo "Hello, $name!"
    
  • 特点
    • -p 选项用于显示提示信息。
    • 输入内容存储在变量中(如 name)。

多输入

  • 可以同时读取多个输入:
    read -p "Enter your first and last name: " first last
    echo "Hello, $first $last!"
    

隐藏输入(如密码)

  • 使用 -s 选项隐藏输入内容:
    read -s -p "Enter your password: " password
    echo "Password entered."
    

2. Python 中的 input()

在 Python 中,input() 是一个内置函数,用于从用户获取输入。

基本用法

  • 语法
    name = input("Enter your name: ")
    print(f"Hello, {name}!")
    
  • 特点
    • 输入内容始终作为字符串返回。
    • 如果需要其他类型(如整数),需显式转换:
      age = int(input("Enter your age: "))
      print(f"You are {age} years old.")
      

多输入

  • 使用 split() 方法处理多输入:
    first, last = input("Enter your first and last name: ").split()
    print(f"Hello, {first} {last}!")
    

隐藏输入(如密码)

  • 使用 getpass 模块隐藏输入内容:
    from getpass import getpass
    password = getpass("Enter your password: ")
    print("Password entered.")
    

3. Golang 中的 fmt.Scan()bufio

在 Golang 中,获取用户输入可以通过 fmt.Scan()bufio 包实现。

fmt.Scan()

  • 基本用法
    package main
    import "fmt"
    func main() {var name stringfmt.Print("Enter your name: ")fmt.Scan(&name)fmt.Printf("Hello, %s!\n", name)
    }
    
  • 特点
    • 输入内容存储到变量中(如 name)。
    • 支持多输入:
      var first, last string
      fmt.Print("Enter your first and last name: ")
      fmt.Scan(&first, &last)
      fmt.Printf("Hello, %s %s!\n", first, last)
      

bufio

  • 基本用法
    package main
    import ("bufio""fmt""os"
    )
    func main() {reader := bufio.NewReader(os.Stdin)fmt.Print("Enter your name: ")name, _ := reader.ReadString('\n')fmt.Printf("Hello, %s!", name)
    }
    
  • 特点
    • 读取整行输入,包括换行符。
    • 需要手动去除换行符:
      name = strings.TrimSpace(name)
      

隐藏输入(如密码)

  • 使用 terminal 包隐藏输入内容:
    package main
    import ("fmt""golang.org/x/term""syscall"
    )
    func main() {fmt.Print("Enter your password: ")password, _ := term.ReadPassword(int(syscall.Stdin))fmt.Println("\nPassword entered.")
    }
    

对比总结

特性 Shell (read) Python (input()) Golang (fmt.Scan())
基本用法 read -p input() fmt.Scan()
多输入支持 支持 支持(需 split() 支持
输入类型 字符串 字符串(需显式转换) 支持多种类型
隐藏输入 read -s getpass.getpass() term.ReadPassword()
读取整行 默认行为 默认行为 bufio.NewReader()

示例代码

Shell

read -p "Enter your name: " name
echo "Hello, $name!"

Python

name = input("Enter your name: ")
print(f"Hello, {name}!")

Golang

package main
import "fmt"
func main() {var name stringfmt.Print("Enter your name: ")fmt.Scan(&name)fmt.Printf("Hello, %s!\n", name)
}

代码缩进

1. Shell 中的缩进

在 Shell 脚本中,缩进主要是为了提高代码的可读性,不会影响代码的执行逻辑。

基本规范

  • 推荐使用 2 或 4 个空格作为缩进单位。
  • 避免使用 Tab 键,因为不同环境下 Tab 的显示可能不一致。
  • 条件语句和循环语句通常需要缩进:
    if [ "$name" == "Alice" ]; thenecho "Hello, Alice!"
    elseecho "Hello, stranger!"
    fi
    
  • 函数定义也需要缩进:
    greet() {echo "Hello, World!"
    }
    

示例

#!/bin/bash
# 缩进示例
for i in {1..5}; doif [ $i -eq 3 ]; thenecho "Found 3!"elseecho "Number: $i"fi
done

2. Python 中的缩进

在 Python 中,缩进是语法的一部分,直接影响代码的执行逻辑。

基本规范

  • 强制使用缩进来表示代码块。
  • 推荐使用 4 个空格作为缩进单位。
  • 避免混合使用空格和 Tab,建议在编辑器中设置 Tab 为 4 个空格。
  • 条件语句、循环语句、函数定义和类定义都需要缩进:
    if name == "Alice":print("Hello, Alice!")
    else:print("Hello, stranger!")
    

示例

# 缩进示例
def greet(name):if name == "Alice":print("Hello, Alice!")else:print("Hello, stranger!")
for i in range(1, 6):if i == 3:print("Found 3!")else:print(f"Number: {i}")

3. Golang 中的缩进

在 Golang 中,缩进主要是为了提高代码的可读性,不会影响代码的执行逻辑。

基本规范

  • 推荐使用 Tab 键作为缩进单位,这是 Golang 的官方规范。
  • 代码块(如函数、条件语句、循环语句)需要缩进:
    if name == "Alice" {fmt.Println("Hello, Alice!")
    } else {fmt.Println("Hello, stranger!")
    }
    
  • 函数定义也需要缩进:
    func greet(name string) {fmt.Printf("Hello, %s!\n", name)
    }
    

示例

package main
import "fmt"
// 缩进示例
func main() {name := "Alice"if name == "Alice" {fmt.Println("Hello, Alice!")} else {fmt.Println("Hello, stranger!")}for i := 1; i <= 5; i++ {if i == 3 {fmt.Println("Found 3!")} else {fmt.Printf("Number: %d\n", i)}}
}

对比总结

特性 Shell Python Golang
缩进是否强制
推荐缩进单位 2 或 4 个空格 4 个空格 Tab
代码块是否缩进
混合空格和 Tab 不推荐 禁止 不推荐
示例 if [ ]; then + 缩进 if: + 缩进 if { + 缩进

代码编写规范

1. Shell 脚本编写规范

命名规范

  • 变量名:使用大写字母和下划线,如 MY_VARIABLE
  • 函数名:使用小写字母和下划线,如 my_function
  • 脚本名:使用小写字母和下划线,如 my_script.sh

注释

  • 单行注释:使用 #
    # 这是一个单行注释
    
  • 多行注释:使用 :<<'EOF' 或连续的单行注释。
  :<<'EOF'这是一个多行注释EOF

代码结构

  • Shebang:在脚本开头指定解释器,如 #!/bin/bash
  • 变量定义:在脚本开头定义变量。
  • 函数定义:在脚本中部定义函数。
  • 主逻辑:在脚本尾部编写主逻辑。

示例

#!/bin/bash
# 脚本名称: my_script.sh
# 描述: 这是一个示例脚本
# 变量定义
MY_VARIABLE="Hello, World!"
# 函数定义
my_function() {echo "$MY_VARIABLE"
}
# 主逻辑
my_function

2. Python 编写规范

命名规范

  • 变量名:使用小写字母和下划线,如 my_variable
  • 函数名:使用小写字母和下划线,如 my_function
  • 类名:使用驼峰命名法,如 MyClass
  • 模块名:使用小写字母和下划线,如 my_module.py

注释

  • 单行注释:使用 #
    # 这是一个单行注释
    
  • 多行注释:使用三引号 """'''
    """
    这是一个
    多行注释
    """
    

代码结构

  • 导入模块:在脚本开头导入模块。
  • 常量定义:在模块级别定义常量。
  • 函数定义:在模块级别定义函数。
  • 类定义:在模块级别定义类。
  • 主逻辑:使用 if __name__ == "__main__": 包裹主逻辑。

示例

# 模块名称: my_module.py
# 描述: 这是一个示例模块
# 导入模块
import sys
# 常量定义
MY_CONSTANT = "Hello, World!"
# 函数定义
def my_function():print(MY_CONSTANT)
# 类定义
class MyClass:def __init__(self):self.message = MY_CONSTANTdef print_message(self):print(self.message)
# 主逻辑
if __name__ == "__main__":my_function()obj = MyClass()obj.print_message()

3. Golang 编写规范

命名规范

  • 变量名:使用驼峰命名法,如 myVariable
  • 函数名:使用驼峰命名法,如 myFunction
  • 类型名:使用驼峰命名法,如 MyType
  • 包名:使用小写字母,如 mypackage

注释

  • 单行注释:使用 //
    // 这是一个单行注释
    
  • 多行注释:使用 /* */
    /*
    这是一个
    多行注释
    */
    

代码结构

  • 包声明:在文件开头声明包名,如 package main
  • 导入包:在包声明后导入包。
  • 常量定义:在包级别定义常量。
  • 变量定义:在包级别定义变量。
  • 函数定义:在包级别定义函数。
  • 类型定义:在包级别定义类型。
  • 主逻辑:在 main 函数中编写主逻辑。

示例

// 包名称: main
// 描述: 这是一个示例程序
// 导入包
import "fmt"
// 常量定义
const myConstant = "Hello, World!"
// 变量定义
var myVariable = myConstant
// 函数定义
func myFunction() {fmt.Println(myVariable)
}
// 类型定义
type MyType struct {message string
}
// 方法定义
func (t *MyType) printMessage() {fmt.Println(t.message)
}
// 主逻辑
func main() {myFunction()obj := MyType{message: myConstant}obj.printMessage()
}

对比总结

特性 Shell Python Golang
命名规范 大写+下划线(变量) 小写+下划线(变量) 驼峰命名法
注释 #:<<'EOF' #""" ///* */
代码结构 Shebang + 变量 + 函数 导入 + 常量 + 函数 + 类 包声明 + 导入 + 常量 + 函数 + 类型
主逻辑 直接编写 if __name__ == "__main__": main 函数

保留字和标识符

1. 保留字(Keywords)

保留字是编程语言中具有特殊含义的单词,不能用作标识符(如变量名、函数名等)。

Shell 中的保留字

Shell 中的保留字包括:

  • 控制结构if, then, else, elif, fi, case, esac, for, while, until, do, done
  • 函数定义function
  • 其他break, continue, return, local, readonly, export

Python 中的保留字

Python 中的保留字包括:

  • 控制结构if, else, elif, for, while, break, continue, pass, return
  • 函数定义def, lambda
  • 类定义class
  • 异常处理try, except, finally, raise
  • 其他import, from, as, with, global, nonlocal, assert, del, yield

Golang 中的保留字

Golang 中的保留字包括:

  • 控制结构if, else, for, switch, case, default, break, continue, return
  • 函数定义func
  • 类型定义type, struct, interface
  • 其他var, const, package, import, go, chan, defer, fallthrough, goto, map, range, select

2. 标识符(Identifiers)

标识符是用户定义的名称,用于变量、函数、类、模块等。标识符的命名需要遵循一定的规则。

Shell 中的标识符

  • 规则
    • 由字母、数字和下划线组成。
    • 不能以数字开头。
    • 区分大小写。
  • 示例
    my_var="Hello"
    MY_VAR="World"
    

Python 中的标识符

  • 规则
    • 由字母、数字和下划线组成。
    • 不能以数字开头。
    • 区分大小写。
    • 不能使用保留字。
  • 示例
    my_var = "Hello"
    MyVar = "World"
    

Golang 中的标识符

  • 规则
    • 由字母、数字和下划线组成。
    • 不能以数字开头。
    • 区分大小写。
    • 不能使用保留字。
  • 示例
    myVar := "Hello"
    MyVar := "World"
    

对比总结

特性 Shell Python Golang
保留字 if, then, for if, else, def if, else, func
标识符规则 字母、数字、下划线 字母、数字、下划线 字母、数字、下划线
是否区分大小写
是否以数字开头
是否使用保留字

最佳实践

  1. 命名规范
    • 使用有意义的名称,避免使用单字母或缩写。
    • 遵循语言的命名约定(如 Python 使用小写+下划线,Golang 使用驼峰命名法)。
  2. 避免冲突
    • 不要使用保留字作为标识符。
    • 避免使用与内置函数或模块同名的标识符。
  3. 一致性
    • 在整个项目中保持命名风格一致。

示例

Shell

# 保留字
if [ "$name" == "Alice" ]; thenecho "Hello, Alice!"
fi
# 标识符
my_var="Hello"
echo $my_var

Python

# 保留字
if name == "Alice":print("Hello, Alice!")
# 标识符
my_var = "Hello"
print(my_var)

Golang

package main
import "fmt"
// 保留字
func main() {if name == "Alice" {fmt.Println("Hello, Alice!")}
}
// 标识符
var myVar = "Hello"
fmt.Println(myVar)

变量定义与使用

1. Shell 中的变量

定义变量

  • 语法
    my_var="Hello, World!"
    
  • 特点
    • 变量名由字母、数字和下划线组成,不能以数字开头。
    • 等号 = 两边不能有空格。
    • 变量值可以是字符串、数字或命令输出。

使用变量

  • 引用变量:使用 $ 符号。
    echo $my_var
    
  • 双引号 vs 单引号
    • 双引号允许变量替换,单引号不允许。
    echo "$my_var"  # 输出: Hello, World!
    echo '$my_var'  # 输出: $my_var
    
  • 命令输出赋值
    current_date=$(date)
    echo "Today is $current_date"
    

示例

#!/bin/bash
# 定义变量
greeting="Hello, World!"
# 使用变量
echo $greeting
# 命令输出赋值
current_date=$(date)
echo "Today is $current_date"

2. Python 中的变量

定义变量

  • 语法
    my_var = "Hello, World!"
    
  • 特点
    • 变量名由字母、数字和下划线组成,不能以数字开头。
    • 变量类型是动态的,无需显式声明。
    • 变量值可以是字符串、数字、列表、字典等。

使用变量

  • 引用变量:直接使用变量名。
    print(my_var)
    
  • 变量类型:可以使用 type() 函数查看。
    print(type(my_var))  # 输出: <class 'str'>
    
  • 多重赋值
    a, b, c = 1, 2, 3
    print(a, b, c)  # 输出: 1 2 3
    

示例

# 定义变量
greeting = "Hello, World!"
# 使用变量
print(greeting)
# 多重赋值
x, y, z = 1, 2, 3
print(x, y, z)

3. Golang 中的变量

定义变量

  • 语法
    var myVar string = "Hello, World!"
    
  • 特点
    • 变量名由字母、数字和下划线组成,不能以数字开头。
    • 变量类型是静态的,需要显式声明。
    • 可以使用 := 进行简短声明(仅限函数内部)。
    myVar := "Hello, World!"
    

使用变量

  • 引用变量:直接使用变量名。
    fmt.Println(myVar)
    
  • 变量类型:可以使用 %T 格式化查看。
    fmt.Printf("Type: %T\n", myVar)  // 输出: Type: string
    
  • 多重赋值
    a, b, c := 1, 2, 3
    fmt.Println(a, b, c)  // 输出: 1 2 3
    

示例

package main
import "fmt"
func main() {// 定义变量var greeting string = "Hello, World!"// 使用变量fmt.Println(greeting)// 简短声明x, y, z := 1, 2, 3fmt.Println(x, y, z)
}

对比总结

特性 Shell Python Golang
定义语法 my_var="value" my_var = "value" var myVar string = "value"
变量类型 动态 动态 静态
简短声明 不支持 不支持 myVar := "value"
多重赋值 不支持 支持 支持
引用变量 $my_var my_var myVar
类型检查 type() %T 格式化

最佳实践

  1. 命名规范
    • 使用有意义的名称,避免使用单字母或缩写。
    • 遵循语言的命名约定(如 Python 使用小写+下划线,Golang 使用驼峰命名法)。
  2. 作用域
    • 在 Shell 中,使用 local 定义局部变量。
    • 在 Python 和 Golang 中,变量作用域由代码块决定。
  3. 类型安全
    • 在 Golang 中,确保变量类型与赋值一致。
    • 在 Python 中,注意动态类型可能带来的问题。

示例

Shell

#!/bin/bash
# 定义变量
greeting="Hello, World!"
# 使用变量
echo $greeting

Python

# 定义变量
greeting = "Hello, World!"
# 使用变量
print(greeting)

Golang

package main
import "fmt"
func main() {// 定义变量var greeting string = "Hello, World!"// 使用变量fmt.Println(greeting)
}

数字类型

1. Shell 中的数字类型

在 Shell 中,数字通常以字符串形式存储,但可以通过命令或运算符进行数值计算。

整数

  • 定义:直接赋值。
    num=10
    
  • 运算:使用 $(( ))expr
    sum=$((num + 5))
    

浮点数

  • 定义:直接赋值。
    pi=3.14
    
  • 运算:使用 bc 命令。
    result=$(echo "scale=2; $pi * 2" | bc)
    

示例

#!/bin/bash
# 整数
num1=10
num2=5
sum=$((num1 + num2))
echo "Sum: $sum"
# 浮点数
pi=3.14
result=$(echo "scale=2; $pi * 2" | bc)
echo "Result: $result"

2. Python 中的数字类型

在 Python 中,数字类型包括整数、浮点数和复数。

整数

  • 定义:直接赋值。
    num = 10
    
  • 运算:支持加减乘除等操作。
    sum = num + 5
    

浮点数

  • 定义:直接赋值。
    pi = 3.14
    
  • 运算:支持加减乘除等操作。
    result = pi * 2
    

复数

  • 定义:使用 j 表示虚部。
    complex_num = 3 + 4j
    
  • 运算:支持加减乘除等操作。
    result = complex_num * 2
    

示例

# 整数
num1 = 10
num2 = 5
sum = num1 + num2
print(f"Sum: {sum}")
# 浮点数
pi = 3.14
result = pi * 2
print(f"Result: {result}")
# 复数
complex_num = 3 + 4j
result = complex_num * 2
print(f"Complex Result: {result}")

3. Golang 中的数字类型

在 Golang 中,数字类型包括整数、浮点数和复数。

整数

  • 定义:使用 intint8int16int32int64 等类型。
    var num int = 10
    
  • 运算:支持加减乘除等操作。
    sum := num + 5
    

浮点数

  • 定义:使用 float32float64 类型。
    var pi float64 = 3.14
    
  • 运算:支持加减乘除等操作。
    result := pi * 2
    

复数

  • 定义:使用 complex64complex128 类型。
    var complexNum complex128 = 3 + 4i
    
  • 运算:支持加减乘除等操作。
    result := complexNum * 2
    

示例

package main
import "fmt"
func main() {// 整数var num1 int = 10var num2 int = 5sum := num1 + num2fmt.Printf("Sum: %d\n", sum)// 浮点数var pi float64 = 3.14result := pi * 2fmt.Printf("Result: %.2f\n", result)// 复数var complexNum complex128 = 3 + 4iresultComplex := complexNum * 2fmt.Printf("Complex Result: %v\n", resultComplex)
}

对比总结

特性 Shell Python Golang
整数类型 字符串形式 int int, int8, int16
浮点数类型 字符串形式 float float32, float64
复数类型 不支持 complex complex64, complex128
运算支持 需要命令或运算符 内置支持 内置支持
类型安全 动态类型 静态类型

最佳实践

  1. 类型选择
    • 在 Golang 中,根据需求选择合适的整数或浮点数类型。
    • 在 Python 中,注意浮点数的精度问题。
  2. 运算效率
    • 在 Golang 中,使用 intfloat64 作为默认类型。
    • 在 Python 中,避免频繁的类型转换。
  3. 类型检查
    • 在 Golang 中,确保变量类型与赋值一致。
    • 在 Python 中,使用 type() 函数检查变量类型。

示例

Shell

#!/bin/bash
# 整数
num1=10
num2=5
sum=$((num1 + num2))
echo "Sum: $sum"
# 浮点数
pi=3.14
result=$(echo "scale=2; $pi * 2" | bc)
echo "Result: $result"

Python

# 整数
num1 = 10
num2 = 5
sum = num1 + num2
print(f"Sum: {sum}")
# 浮点数
pi = 3.14
result = pi * 2
print(f"Result: {result}")
# 复数
complex_num = 3 + 4j
result = complex_num * 2
print(f"Complex Result: {result}")

Golang

package main
import "fmt"
func main() {// 整数var num1 int = 10var num2 int = 5sum := num1 + num2fmt.Printf("Sum: %d\n", sum)// 浮点数var pi float64 = 3.14result := pi * 2fmt.Printf("Result: %.2f\n", result)// 复数var complexNum complex128 = 3 + 4iresultComplex := complexNum * 2fmt.Printf("Complex Result: %v\n", resultComplex)
}

字符串类型

1. Shell 中的字符串

在 Shell 中,字符串是常见的数据类型,通常用引号包裹。

定义字符串

  • 单引号:原样输出,不支持变量替换。
    str='Hello, World!'
    
  • 双引号:支持变量替换。
    name="Alice"
    str="Hello, $name!"
    

字符串操作

  • 拼接:直接连接。
    str1="Hello, "
    str2="World!"
    result="$str1$str2"
    
  • 长度:使用 ${#str}
    length=${#str}
    
  • 子字符串:使用 ${str:start:length}
    substr=${str:0:5}
    

示例

#!/bin/bash
# 定义字符串
name="Alice"
str="Hello, $name!"
# 字符串操作
length=${#str}
substr=${str:0:5}
# 输出
echo "String: $str"
echo "Length: $length"
echo "Substring: $substr"

2. Python 中的字符串

在 Python 中,字符串是不可变的序列类型。

定义字符串

  • 单引号
    str1 = 'Hello, World!'
    
  • 双引号
    str2 = "Hello, World!"
    
  • 三引号:多行字符串。
    str3 = """Hello,
    World!"""
    

字符串操作

  • 拼接:使用 +join()
    result = str1 + " " + str2
    
  • 长度:使用 len()
    length = len(str1)
    
  • 子字符串:使用切片。
    substr = str1[0:5]
    
  • 格式化:使用 f-stringformat()%
    name = "Alice"
    str4 = f"Hello, {name}!"
    

示例

# 定义字符串
str1 = 'Hello, World!'
str2 = "Hello, World!"
str3 = """Hello,
World!"""
# 字符串操作
result = str1 + " " + str2
length = len(str1)
substr = str1[0:5]
name = "Alice"
str4 = f"Hello, {name}!"
# 输出
print("String 1:", str1)
print("String 2:", str2)
print("String 3:", str3)
print("Concatenated:", result)
print("Length:", length)
print("Substring:", substr)
print("Formatted:", str4)

3. Golang 中的字符串

在 Golang 中,字符串是只读的字节切片。

定义字符串

  • 双引号
    str1 := "Hello, World!"
    
  • 反引号:原样输出,支持多行。
    str2 := `Hello,
    World!`
    

字符串操作

  • 拼接:使用 +fmt.Sprintf()
    result := str1 + " " + str2
    
  • 长度:使用 len()
    length := len(str1)
    
  • 子字符串:使用切片。
    substr := str1[0:5]
    
  • 格式化:使用 fmt.Sprintf()
    name := "Alice"
    str3 := fmt.Sprintf("Hello, %s!", name)
    

示例

package main
import "fmt"
func main() {// 定义字符串str1 := "Hello, World!"str2 := `Hello,World!`// 字符串操作result := str1 + " " + str2length := len(str1)substr := str1[0:5]name := "Alice"str3 := fmt.Sprintf("Hello, %s!", name)// 输出fmt.Println("String 1:", str1)fmt.Println("String 2:", str2)fmt.Println("Concatenated:", result)fmt.Println("Length:", length)fmt.Println("Substring:", substr)fmt.Println("Formatted:", str3)
}

对比总结

特性 Shell Python Golang
定义方式 单引号、双引号 单引号、双引号、三引号 双引号、反引号
变量替换 双引号支持 f-stringformat() fmt.Sprintf()
拼接 直接连接 +join() +fmt.Sprintf()
长度 ${#str} len() len()
子字符串 ${str:start:length} 切片 切片
多行字符串 不支持 三引号 反引号

最佳实践

  1. 格式化字符串
    • 在 Python 中使用 f-string,在 Golang 中使用 fmt.Sprintf()
  2. 字符串拼接
    • 在 Python 中,使用 join() 拼接大量字符串以提高性能。
    • 在 Golang 中,使用 strings.Builder 拼接大量字符串。
  3. 字符编码
    • 在 Python 和 Golang 中,注意字符串的编码问题(如 UTF-8)。

示例

Shell

#!/bin/bash
# 定义字符串
name="Alice"
str="Hello, $name!"
# 字符串操作
length=${#str}
substr=${str:0:5}
# 输出
echo "String: $str"
echo "Length: $length"
echo "Substring: $substr"

Python

# 定义字符串
str1 = 'Hello, World!'
str2 = "Hello, World!"
str3 = """Hello,
World!"""
# 字符串操作
result = str1 + " " + str2
length = len(str1)
substr = str1[0:5]
name = "Alice"
str4 = f"Hello, {name}!"
# 输出
print("String 1:", str1)
print("String 2:", str2)
print("String 3:", str3)
print("Concatenated:", result)
print("Length:", length)
print("Substring:", substr)
print("Formatted:", str4)

Golang

package main
import "fmt"
func main() {// 定义字符串str1 := "Hello, World!"str2 := `Hello,World!`// 字符串操作result := str1 + " " + str2length := len(str1)substr := str1[0:5]name := "Alice"str3 := fmt.Sprintf("Hello, %s!", name)// 输出fmt.Println("String 1:", str1)fmt.Println("String 2:", str2)fmt.Println("Concatenated:", result)fmt.Println("Length:", length)fmt.Println("Substring:", substr)fmt.Println("Formatted:", str3)
}

算术运算符

1. Shell 中的算术运算符

在 Shell 中,算术运算通常使用 $(( ))expr 命令。

基本运算符

  • 加法+
    result=$((num1 + num2))
    
  • 减法-
    result=$((num1 - num2))
    
  • 乘法*
    result=$((num1 * num2))
    
  • 除法/
    result=$((num1 / num2))
    
  • 取余%
    result=$((num1 % num2))
    

示例

#!/bin/bash
# 定义变量
num1=10
num2=3
# 算术运算
sum=$((num1 + num2))
diff=$((num1 - num2))
prod=$((num1 * num2))
quot=$((num1 / num2))
mod=$((num1 % num2))
# 输出
echo "Sum: $sum"
echo "Difference: $diff"
echo "Product: $prod"
echo "Quotient: $quot"
echo "Modulus: $mod"

2. Python 中的算术运算符

在 Python 中,算术运算符直接支持整数和浮点数运算。

基本运算符

  • 加法+
    result = num1 + num2
    
  • 减法-
    result = num1 - num2
    
  • 乘法*
    result = num1 * num2
    
  • 除法/
    result = num1 / num2
    
  • 取余%
    result = num1 % num2
    
  • 幂运算**
    result = num1 ** num2
    

示例

# 定义变量
num1 = 10
num2 = 3
# 算术运算
sum = num1 + num2
diff = num1 - num2
prod = num1 * num2
quot = num1 / num2
mod = num1 % num2
power = num1 ** num2
# 输出
print(f"Sum: {sum}")
print(f"Difference: {diff}")
print(f"Product: {prod}")
print(f"Quotient: {quot}")
print(f"Modulus: {mod}")
print(f"Power: {power}")

3. Golang 中的算术运算符

在 Golang 中,算术运算符支持整数和浮点数运算。

基本运算符

  • 加法+
    result := num1 + num2
    
  • 减法-
    result := num1 - num2
    
  • 乘法*
    result := num1 * num2
    
  • 除法/
    result := num1 / num2
    
  • 取余%
    result := num1 % num2
    

示例

package main
import "fmt"
func main() {// 定义变量num1 := 10num2 := 3// 算术运算sum := num1 + num2diff := num1 - num2prod := num1 * num2quot := num1 / num2mod := num1 % num2// 输出fmt.Printf("Sum: %d\n", sum)fmt.Printf("Difference: %d\n", diff)fmt.Printf("Product: %d\n", prod)fmt.Printf("Quotient: %d\n", quot)fmt.Printf("Modulus: %d\n", mod)
}

对比总结

特性 Shell Python Golang
加法 + + +
减法 - - -
乘法 * * *
除法 / / /
取余 % % %
幂运算 不支持 ** 不支持
浮点数运算 使用 bc 命令 直接支持 直接支持
表达式语法 $(( ))expr 直接支持 直接支持

最佳实践

  1. 类型安全
    • 在 Golang 中,确保运算操作数的类型一致。
    • 在 Python 中,注意整数除法和浮点数除法的区别。
  2. 性能优化
    • 在 Shell 中,使用 $(( )) 替代 expr 以提高性能。
    • 在 Python 中,使用 math 模块进行复杂数学运算。
  3. 错误处理
    • 在 Shell 中,检查除零错误。
    • 在 Golang 中,处理可能的溢出或除零错误。

示例

Shell

#!/bin/bash
# 定义变量
num1=10
num2=3
# 算术运算
sum=$((num1 + num2))
diff=$((num1 - num2))
prod=$((num1 * num2))
quot=$((num1 / num2))
mod=$((num1 % num2))
# 输出
echo "Sum: $sum"
echo "Difference: $diff"
echo "Product: $prod"
echo "Quotient: $quot"
echo "Modulus: $mod"

Python

# 定义变量
num1 = 10
num2 = 3
# 算术运算
sum = num1 + num2
diff = num1 - num2
prod = num1 * num2
quot = num1 / num2
mod = num1 % num2
power = num1 ** num2
# 输出
print(f"Sum: {sum}")
print(f"Difference: {diff}")
print(f"Product: {prod}")
print(f"Quotient: {quot}")
print(f"Modulus: {mod}")
print(f"Power: {power}")

Golang

package main
import "fmt"
func main() {// 定义变量num1 := 10num2 := 3// 算术运算sum := num1 + num2diff := num1 - num2prod := num1 * num2quot := num1 / num2mod := num1 % num2// 输出fmt.Printf("Sum: %d\n", sum)fmt.Printf("Difference: %d\n", diff)fmt.Printf("Product: %d\n", prod)fmt.Printf("Quotient: %d\n", quot)fmt.Printf("Modulus: %d\n", mod)
}

索引

1. Shell 中的索引

在 Shell 中,索引主要用于访问字符串或数组中的元素。

字符串索引

  • 语法:使用 ${str:start:length}
    str="Hello, World!"
    substr=${str:0:5}  # 获取前5个字符
    

数组索引

  • 语法:使用 ${array[index]}
    array=("Alice" "Bob" "Charlie")
    echo ${array[1]}  # 输出: Bob
    

示例

#!/bin/bash
# 字符串索引
str="Hello, World!"
substr=${str:0:5}
echo "Substring: $substr"
# 数组索引
array=("Alice" "Bob" "Charlie")
echo "Second element: ${array[1]}"

2. Python 中的索引

在 Python 中,索引用于访问字符串、列表、元组等序列类型中的元素。

字符串索引

  • 语法:使用 str[index]
    str = "Hello, World!"
    char = str[0]  # 获取第一个字符
    
  • 切片:使用 str[start:end]
    substr = str[0:5]  # 获取前5个字符
    

列表索引

  • 语法:使用 list[index]
    list = ["Alice", "Bob", "Charlie"]
    element = list[1]  # 获取第二个元素
    

示例

# 字符串索引
str = "Hello, World!"
char = str[0]
substr = str[0:5]
print("First character:", char)
print("Substring:", substr)
# 列表索引
list = ["Alice", "Bob", "Charlie"]
element = list[1]
print("Second element:", element)

3. Golang 中的索引

在 Golang 中,索引用于访问字符串、数组、切片等类型中的元素。

字符串索引

  • 语法:使用 str[index]
    str := "Hello, World!"
    char := str[0]  // 获取第一个字符
    
  • 切片:使用 str[start:end]
    substr := str[0:5]  // 获取前5个字符
    

数组/切片索引

  • 语法:使用 array[index]
    array := [3]string{"Alice", "Bob", "Charlie"}
    element := array[1]  // 获取第二个元素
    

示例

package main
import "fmt"
func main() {// 字符串索引str := "Hello, World!"char := str[0]substr := str[0:5]fmt.Printf("First character: %c\n", char)fmt.Println("Substring:", substr)// 数组索引array := [3]string{"Alice", "Bob", "Charlie"}element := array[1]fmt.Println("Second element:", element)
}

对比总结

特性 Shell Python Golang
字符串索引 ${str:start:length} str[index] str[index]
字符串切片 ${str:start:length} str[start:end] str[start:end]
数组/列表索引 ${array[index]} list[index] array[index]
索引从 0 开始
支持负索引
类型安全 动态类型 静态类型

最佳实践

  1. 边界检查
    • 在 Golang 中,确保索引在有效范围内,否则会引发运行时错误。
    • 在 Python 中,使用负索引时注意其含义(从末尾开始计数)。
  2. 切片操作
    • 在 Python 和 Golang 中,切片操作返回一个新的序列,不会修改原序列。
  3. 性能优化
    • 在 Golang 中,使用切片代替数组以提高灵活性。
    • 在 Python 中,使用列表推导式或生成器表达式处理大量数据。

示例

Shell

#!/bin/bash
# 字符串索引
str="Hello, World!"
substr=${str:0:5}
echo "Substring: $substr"
# 数组索引
array=("Alice" "Bob" "Charlie")
echo "Second element: ${array[1]}"

Python

# 字符串索引
str = "Hello, World!"
char = str[0]
substr = str[0:5]
print("First character:", char)
print("Substring:", substr)
# 列表索引
list = ["Alice", "Bob", "Charlie"]
element = list[1]
print("Second element:", element)

Golang

package main
import "fmt"
func main() {// 字符串索引str := "Hello, World!"char := str[0]substr := str[0:5]fmt.Printf("First character: %c\n", char)fmt.Println("Substring:", substr)// 数组索引array := [3]string{"Alice", "Bob", "Charlie"}element := array[1]fmt.Println("Second element:", element)
}

切片

1. Shell 中的切片

在 Shell 中,切片主要用于字符串和数组。

字符串切片

  • 语法:使用 ${str:start:length}
    str="Hello, World!"
    substr=${str:0:5}  # 获取前5个字符
    

数组切片

  • 语法:使用 ${array[@]:start:length}
    array=("Alice" "Bob" "Charlie" "David")
    subarray=("${array[@]:1:2}")  # 获取第2到第3个元素
    

示例

#!/bin/bash
# 字符串切片
str="Hello, World!"
substr=${str:0:5}
echo "Substring: $substr"
# 数组切片
array=("Alice" "Bob" "Charlie" "David")
subarray=("${array[@]:1:2}")
echo "Subarray: ${subarray[@]}"

2. Python 中的切片

在 Python 中,切片用于字符串、列表、元组等序列类型。

字符串切片

  • 语法:使用 str[start:end:step]
    str = "Hello, World!"
    substr = str[0:5]  # 获取前5个字符
    
  • 步长:使用 step 参数。
    substr = str[::2]  # 每隔一个字符取一个
    

列表切片

  • 语法:使用 list[start:end:step]
    list = ["Alice", "Bob", "Charlie", "David"]
    sublist = list[1:3]  # 获取第2到第3个元素
    

示例

# 字符串切片
str = "Hello, World!"
substr = str[0:5]
print("Substring:", substr)
# 列表切片
list = ["Alice", "Bob", "Charlie", "David"]
sublist = list[1:3]
print("Sublist:", sublist)
# 步长切片
substr_step = str[::2]
print("Step slicing:", substr_step)

3. Golang 中的切片

在 Golang 中,切片是动态数组,支持灵活的切片操作。

字符串切片

  • 语法:使用 str[start:end]
    str := "Hello, World!"
    substr := str[0:5]  // 获取前5个字符
    

切片类型

  • 语法:使用 slice[start:end]
    slice := []string{"Alice", "Bob", "Charlie", "David"}
    subslice := slice[1:3]  // 获取第2到第3个元素
    

示例

package main
import "fmt"
func main() {// 字符串切片str := "Hello, World!"substr := str[0:5]fmt.Println("Substring:", substr)// 切片类型slice := []string{"Alice", "Bob", "Charlie", "David"}subslice := slice[1:3]fmt.Println("Subslice:", subslice)
}

对比总结

特性 Shell Python Golang
字符串切片 ${str:start:length} str[start:end:step] str[start:end]
数组/列表切片 ${array[@]:start:length} list[start:end:step] slice[start:end]
步长支持 不支持 支持 不支持
索引从 0 开始
支持负索引
类型安全 动态类型 静态类型

最佳实践

  1. 边界检查
    • 在 Golang 中,确保切片范围在有效范围内,否则会引发运行时错误。
    • 在 Python 中,使用负索引时注意其含义(从末尾开始计数)。
  2. 性能优化
    • 在 Golang 中,切片是引用类型,修改子切片会影响原切片。
    • 在 Python 中,切片操作返回一个新的序列,不会修改原序列。
  3. 代码简洁
    • 在 Python 中,使用步长切片简化代码。
    • 在 Golang 中,使用切片代替数组以提高灵活性。

示例

Shell

#!/bin/bash
# 字符串切片
str="Hello, World!"
substr=${str:0:5}
echo "Substring: $substr"
# 数组切片
array=("Alice" "Bob" "Charlie" "David")
subarray=("${array[@]:1:2}")
echo "Subarray: ${subarray[@]}"

Python

# 字符串切片
str = "Hello, World!"
substr = str[0:5]
print("Substring:", substr)
# 列表切片
list = ["Alice", "Bob", "Charlie", "David"]
sublist = list[1:3]
print("Sublist:", sublist)
# 步长切片
substr_step = str[::2]
print("Step slicing:", substr_step)

Golang

package main
import "fmt"
func main() {// 字符串切片str := "Hello, World!"substr := str[0:5]fmt.Println("Substring:", substr)// 切片类型slice := []string{"Alice", "Bob", "Charlie", "David"}subslice := slice[1:3]fmt.Println("Subslice:", subslice)
}

正则表达式

1. Shell 中的正则表达式

在 Shell 中,正则表达式通常与 grepsedawk 等工具结合使用。

匹配

  • 语法:使用 grep
    echo "Hello, World!" | grep -E "Hello"
    

替换

  • 语法:使用 sed
    echo "Hello, World!" | sed 's/Hello/Hi/'
    

分割

  • 语法:使用 awk
    echo "Hello,World,Shell" | awk -F, '{print $1, $2, $3}'
    

示例

#!/bin/bash
# 匹配
echo "Hello, World!" | grep -E "Hello"
# 替换
echo "Hello, World!" | sed 's/Hello/Hi/'
# 分割
echo "Hello,World,Shell" | awk -F, '{print $1, $2, $3}'

2. Python 中的正则表达式

在 Python 中,正则表达式通过 re 模块实现。

匹配

  • 语法:使用 re.match()re.search()
    import re
    result = re.search(r"Hello", "Hello, World!")
    

替换

  • 语法:使用 re.sub()
    result = re.sub(r"Hello", "Hi", "Hello, World!")
    

分割

  • 语法:使用 re.split()
    result = re.split(r",", "Hello,World,Python")
    

示例

import re
# 匹配
match = re.search(r"Hello", "Hello, World!")
if match:print("Match found:", match.group())
# 替换
result = re.sub(r"Hello", "Hi", "Hello, World!")
print("Replaced string:", result)
# 分割
result = re.split(r",", "Hello,World,Python")
print("Split result:", result)

3. Golang 中的正则表达式

在 Golang 中,正则表达式通过 regexp 包实现。

匹配

  • 语法:使用 regexp.MatchString()regexp.FindString()
    matched, _ := regexp.MatchString(`Hello`, "Hello, World!")
    

替换

  • 语法:使用 regexp.ReplaceAllString()
    result := regexp.MustCompile(`Hello`).ReplaceAllString("Hello, World!", "Hi")
    

分割

  • 语法:使用 regexp.Split()
    result := regexp.MustCompile(`,`).Split("Hello,World,Golang", -1)
    

示例

package main
import ("fmt""regexp"
)
func main() {// 匹配matched, _ := regexp.MatchString(`Hello`, "Hello, World!")fmt.Println("Match found:", matched)// 替换result := regexp.MustCompile(`Hello`).ReplaceAllString("Hello, World!", "Hi")fmt.Println("Replaced string:", result)// 分割resultSplit := regexp.MustCompile(`,`).Split("Hello,World,Golang", -1)fmt.Println("Split result:", resultSplit)
}

对比总结

特性 Shell Python Golang
匹配 grep re.match()re.search() regexp.MatchString()regexp.FindString()
替换 sed re.sub() regexp.ReplaceAllString()
分割 awk re.split() regexp.Split()
正则表达式语法 基本支持 完整支持 完整支持
性能 高效 中等 高效

最佳实践

  1. 正则表达式语法
    • 在 Python 和 Golang 中,使用原始字符串(r""` `)避免转义问题。
    • 在 Shell 中,使用 -E 选项启用扩展正则表达式。
  2. 性能优化
    • 在 Golang 中,使用 regexp.MustCompile() 预编译正则表达式以提高性能。
    • 在 Python 中,使用 re.compile() 预编译正则表达式。
  3. 错误处理
    • 在 Golang 中,检查正则表达式编译和匹配的错误。
    • 在 Python 中,使用 try-except 捕获异常。

示例

Shell

#!/bin/bash
# 匹配
echo "Hello, World!" | grep -E "Hello"
# 替换
echo "Hello, World!" | sed 's/Hello/Hi/'
# 分割
echo "Hello,World,Shell" | awk -F, '{print $1, $2, $3}'

Python

import re
# 匹配
match = re.search(r"Hello", "Hello, World!")
if match:print("Match found:", match.group())
# 替换
result = re.sub(r"Hello", "Hi", "Hello, World!")
print("Replaced string:", result)
# 分割
result = re.split(r",", "Hello,World,Python")
print("Split result:", result)

Golang

package main
import ("fmt""regexp"
)
func main() {// 匹配matched, _ := regexp.MatchString(`Hello`, "Hello, World!")fmt.Println("Match found:", matched)// 替换result := regexp.MustCompile(`Hello`).ReplaceAllString("Hello, World!", "Hi")fmt.Println("Replaced string:", result)// 分割resultSplit := regexp.MustCompile(`,`).Split("Hello,World,Golang", -1)fmt.Println("Split result:", resultSplit)
}

数据库编程(MySQL、PostgreSQL)

1. Python 中的数据库编程

在 Python 中,常用的数据库接口是 DB-API,具体实现包括 mysql-connector-pythonpsycopg2

操作 MySQL

  • 安装库
    pip install mysql-connector-python
    
  • 连接数据库
    import mysql.connector
    conn = mysql.connector.connect(host="localhost",user="root",password="password",database="testdb"
    )
    
  • 执行查询
    cursor = conn.cursor()
    cursor.execute("SELECT * FROM users")
    rows = cursor.fetchall()
    for row in rows:print(row)
    
  • 插入数据
    cursor.execute("INSERT INTO users (name, age) VALUES (%s, %s)", ("Alice", 30))
    conn.commit()
    

操作 PostgreSQL

  • 安装库
    pip install psycopg2
    
  • 连接数据库
    import psycopg2
    conn = psycopg2.connect(host="localhost",user="postgres",password="password",database="testdb"
    )
    
  • 执行查询
    cursor = conn.cursor()
    cursor.execute("SELECT * FROM users")
    rows = cursor.fetchall()
    for row in rows:print(row)
    
  • 插入数据
    cursor.execute("INSERT INTO users (name, age) VALUES (%s, %s)", ("Alice", 30))
    conn.commit()
    

示例

# MySQL 示例
import mysql.connector
conn = mysql.connector.connect(host="localhost",user="root",password="password",database="testdb"
)
cursor = conn.cursor()
cursor.execute("SELECT * FROM users")
rows = cursor.fetchall()
for row in rows:print(row)
cursor.execute("INSERT INTO users (name, age) VALUES (%s, %s)", ("Alice", 30))
conn.commit()
conn.close()
# PostgreSQL 示例
import psycopg2
conn = psycopg2.connect(host="localhost",user="postgres",password="password",database="testdb"
)
cursor = conn.cursor()
cursor.execute("SELECT * FROM users")
rows = cursor.fetchall()
for row in rows:print(row)
cursor.execute("INSERT INTO users (name, age) VALUES (%s, %s)", ("Alice", 30))
conn.commit()
conn.close()

2. Golang 中的数据库编程

在 Golang 中,常用的数据库接口是 database/sql,具体实现包括 mysqlpq

操作 MySQL

  • 安装库
    go get -u github.com/go-sql-driver/mysql
    
  • 连接数据库
    import ("database/sql"_ "github.com/go-sql-driver/mysql"
    )
    db, err := sql.Open("mysql", "root:password@tcp(localhost:3306)/testdb")
    
  • 执行查询
    rows, err := db.Query("SELECT * FROM users")
    for rows.Next() {var id intvar name stringvar age introws.Scan(&id, &name, &age)fmt.Println(id, name, age)
    }
    
  • 插入数据
    result, err := db.Exec("INSERT INTO users (name, age) VALUES (?, ?)", "Alice", 30)
    

操作 PostgreSQL

  • 安装库
    go get -u github.com/lib/pq
    
  • 连接数据库
    import ("database/sql"_ "github.com/lib/pq"
    )
    db, err := sql.Open("postgres", "user=postgres password=password dbname=testdb sslmode=disable")
    
  • 执行查询
    rows, err := db.Query("SELECT * FROM users")
    for rows.Next() {var id intvar name stringvar age introws.Scan(&id, &name, &age)fmt.Println(id, name, age)
    }
    
  • 插入数据
    result, err := db.Exec("INSERT INTO users (name, age) VALUES ($1, $2)", "Alice", 30)
    

示例

// MySQL 示例
package main
import ("database/sql""fmt"_ "github.com/go-sql-driver/mysql"
)
func main() {db, err := sql.Open("mysql", "root:password@tcp(localhost:3306)/testdb")if err != nil {panic(err)}defer db.Close()rows, err := db.Query("SELECT * FROM users")if err != nil {panic(err)}for rows.Next() {var id intvar name stringvar age introws.Scan(&id, &name, &age)fmt.Println(id, name, age)}result, err := db.Exec("INSERT INTO users (name, age) VALUES (?, ?)", "Alice", 30)if err != nil {panic(err)}fmt.Println(result.LastInsertId())
}
// PostgreSQL 示例
package main
import ("database/sql""fmt"_ "github.com/lib/pq"
)
func main() {db, err := sql.Open("postgres", "user=postgres password=password dbname=testdb sslmode=disable")if err != nil {panic(err)}defer db.Close()rows, err := db.Query("SELECT * FROM users")if err != nil {panic(err)}for rows.Next() {var id intvar name stringvar age introws.Scan(&id, &name, &age)fmt.Println(id, name, age)}result, err := db.Exec("INSERT INTO users (name, age) VALUES ($1, $2)", "Alice", 30)if err != nil {panic(err)}fmt.Println(result.LastInsertId())
}

对比总结

特性 Python (MySQL) Python (PostgreSQL) Golang (MySQL) Golang (PostgreSQL)
库名 mysql-connector-python psycopg2 github.com/go-sql-driver/mysql github.com/lib/pq
连接字符串 host, user, password, database host, user, password, database user:password@tcp(host:port)/db user=user password=password dbname=db sslmode=disable
查询 cursor.execute() cursor.execute() db.Query() db.Query()
插入 cursor.execute() cursor.execute() db.Exec() db.Exec()
事务 conn.commit() conn.commit() db.Begin() db.Begin()
错误处理 try-except try-except if err != nil if err != nil

最佳实践

  1. 连接池
    • 在 Golang 中,database/sql 默认支持连接池。
    • 在 Python 中,使用 mysql-connector-pythonpsycopg2 的连接池功能。
  2. 事务管理
    • 在 Golang 中,使用 db.Begin()tx.Commit() 管理事务。
    • 在 Python 中,使用 conn.commit() 提交事务。
  3. 错误处理
    • 在 Golang 中,检查每个操作的错误。
    • 在 Python 中,使用 try-except 捕获异常。

示例

Python (MySQL)

import mysql.connector
conn = mysql.connector.connect(host="localhost",user="root",password="password",database="testdb"
)
cursor = conn.cursor()
cursor.execute("SELECT * FROM users")
rows = cursor.fetchall()
for row in rows:print(row)
cursor.execute("INSERT INTO users (name, age) VALUES (%s, %s)", ("Alice", 30))
conn.commit()
conn.close()

Python (PostgreSQL)

import psycopg2
conn = psycopg2.connect(host="localhost",user="postgres",password="password",database="testdb"
)
cursor = conn.cursor()
cursor.execute("SELECT * FROM users")
rows = cursor.fetchall()
for row in rows:print(row)
cursor.execute("INSERT INTO users (name, age) VALUES (%s, %s)", ("Alice", 30))
conn.commit()
conn.close()

Golang (MySQL)

package main
import ("database/sql""fmt"_ "github.com/go-sql-driver/mysql"
)
func main() {db, err := sql.Open("mysql", "root:password@tcp(localhost:3306)/testdb")if err != nil {panic(err)}defer db.Close()rows, err := db.Query("SELECT * FROM users")if err != nil {panic(err)}for rows.Next() {var id intvar name stringvar age introws.Scan(&id, &name, &age)fmt.Println(id, name, age)}result, err := db.Exec("INSERT INTO users (name, age) VALUES (?, ?)", "Alice", 30)if err != nil {panic(err)}fmt.Println(result.LastInsertId())
}

Golang (PostgreSQL)

package main
import ("database/sql""fmt"_ "github.com/lib/pq"
)
func main() {db, err := sql.Open("postgres", "user=postgres password=password dbname=testdb sslmode=disable")if err != nil {panic(err)}defer db.Close()rows, err := db.Query("SELECT * FROM users")if err != nil {panic(err)}for rows.Next() {var id intvar name stringvar age introws.Scan(&id, &name, &age)fmt.Println(id, name, age)}result, err := db.Exec("INSERT INTO users (name, age) VALUES ($1, $2)", "Alice", 30)if err != nil {panic(err)}fmt.Println(result.LastInsertId())
}

多进程编程

1. 创建进程

Shell

  • 语法:使用 & 实现后台运行,使用 wait 等待进程结束。
    command &
    wait
    
  • 示例
    #!/bin/bash
    worker() {echo "Worker $1 is running"sleep 2
    }
    for i in {1..3}; doworker "Process-$i" &
    done
    wait
    echo "All workers are done"
    

Python

  • 语法:使用 multiprocessing.Process
    from multiprocessing import Process
    def worker(name):print(f"Worker {name} is running")
    if __name__ == "__main__":p = Process(target=worker, args=("Alice",))p.start()p.join()
    
  • 示例
    from multiprocessing import Process
    def worker(name):print(f"Worker {name} is running")
    if __name__ == "__main__":processes = []for i in range(3):p = Process(target=worker, args=(f"Process-{i}",))processes.append(p)p.start()for p in processes:p.join()
    

Golang

  • 语法:使用 go 关键字启动 goroutine
    go func() {fmt.Println("Worker is running")
    }()
    
  • 示例
    package main
    import ("fmt""sync"
    )
    func worker(wg *sync.WaitGroup, name string) {defer wg.Done()fmt.Printf("Worker %s is running\n", name)
    }
    func main() {var wg sync.WaitGroupfor i := 1; i <= 3; i++ {wg.Add(1)go worker(&wg, fmt.Sprintf("Process-%d", i))}wg.Wait()fmt.Println("All workers are done")
    }
    

2. 进程池

Shell

  • 语法:通过控制后台进程数量实现。
    max_jobs=3
    for i in {1..10}; dowhile [ $(jobs -r | wc -l) -ge $max_jobs ]; dosleep 1doneworker "Process-$i" &
    done
    wait
    

Python

  • 语法:使用 multiprocessing.Pool
    from multiprocessing import Pool
    def worker(name):return f"Worker {name} is done"
    if __name__ == "__main__":with Pool(3) as pool:results = pool.map(worker, ["Alice", "Bob", "Charlie"])print(results)
    

Golang

  • 语法:使用 channel 控制并发数量。
    package main
    import ("fmt""sync"
    )
    func worker(wg *sync.WaitGroup, name string) {defer wg.Done()fmt.Printf("Worker %s is running\n", name)
    }
    func main() {var wg sync.WaitGroupmaxJobs := 3jobChan := make(chan struct{}, maxJobs)for i := 1; i <= 10; i++ {wg.Add(1)jobChan <- struct{}{}go func(i int) {defer func() { <-jobChan }()worker(&wg, fmt.Sprintf("Process-%d", i))}(i)}wg.Wait()
    }
    

3. 进程间通信

Shell

  • 语法:使用文件或命名管道(FIFO)。
    mkfifo my_pipe
    worker() {echo "Hello from worker $1" > my_pipe
    }
    for i in {1..3}; doworker "Process-$i" &
    done
    for i in {1..3}; doread line < my_pipeecho $line
    done
    rm my_pipe
    

Python

  • 语法:使用 multiprocessing.Queue
    from multiprocessing import Process, Queue
    def worker(q):q.put("Hello from worker")
    if __name__ == "__main__":q = Queue()processes = []for i in range(3):p = Process(target=worker, args=(q,))processes.append(p)p.start()for p in processes:p.join()while not q.empty():print(q.get())
    

Golang

  • 语法:使用 channel
    package main
    import ("fmt""sync"
    )
    func worker(wg *sync.WaitGroup, ch chan string, name string) {defer wg.Done()ch <- fmt.Sprintf("Hello from worker %s", name)
    }
    func main() {var wg sync.WaitGroupch := make(chan string, 3)for i := 1; i <= 3; i++ {wg.Add(1)go worker(&wg, ch, fmt.Sprintf("Process-%d", i))}wg.Wait()close(ch)for msg := range ch {fmt.Println(msg)}
    }
    

对比总结

特性 Shell Python Golang
创建进程 & multiprocessing.Process go
进程池 控制后台进程数量 multiprocessing.Pool channel 控制并发数量
进程间通信 文件或命名管道 multiprocessing.Queue channel
性能 中等 中等 高效
复杂性 中等 中等

最佳实践

  1. 资源管理
    • 在 Shell 中,使用 wait 确保所有后台进程完成。
    • 在 Python 中,使用 join() 等待进程结束。
    • 在 Golang 中,使用 sync.WaitGroup 等待所有 goroutine 完成。
  2. 任务分配
    • 在 Shell 中,通过循环和条件判断控制并发数量。
    • 在 Python 中,使用 Pool.map()Pool.apply_async() 分配任务。
    • 在 Golang 中,使用 channel 实现任务队列。
  3. 错误处理
    • 在 Shell 中,检查命令返回值。
    • 在 Python 中,使用 try-except 捕获异常。
    • 在 Golang 中,使用 deferrecover 处理异常。

示例

Shell

#!/bin/bash
worker() {echo "Worker $1 is running"sleep 2
}
for i in {1..3}; doworker "Process-$i" &
done
wait
echo "All workers are done"

Python

from multiprocessing import Process
def worker(name):print(f"Worker {name} is running")
if __name__ == "__main__":processes = []for i in range(3):p = Process(target=worker, args=(f"Process-{i}",))processes.append(p)p.start()for p in processes:p.join()

Golang

package main
import ("fmt""sync"
)
func worker(wg *sync.WaitGroup, name string) {defer wg.Done()fmt.Printf("Worker %s is running\n", name)
}
func main() {var wg sync.WaitGroupfor i := 1; i <= 3; i++ {wg.Add(1)go worker(&wg, fmt.Sprintf("Process-%d", i))}wg.Wait()fmt.Println("All workers are done")
}

线程编程

1. 什么是线程?

  • 线程 是操作系统能够进行运算调度的最小单位,是进程中的一个执行流。
  • 一个进程可以包含多个线程,所有线程共享进程的内存空间和资源。
  • 线程比进程更轻量,创建和切换的开销更小。

2. 创建线程

Python

  • 语法:使用 threading.Thread
    import threading
    def worker():print("Worker thread is running")
    if __name__ == "__main__":t = threading.Thread(target=worker)t.start()t.join()
    

Golang

  • 语法:使用 goroutine
    package main
    import ("fmt""time"
    )
    func worker() {fmt.Println("Worker goroutine is running")
    }
    func main() {go worker()time.Sleep(time.Second) // 等待 goroutine 完成
    }
    

3. 线程间通信

Python

  • 语法:使用 queue.Queue
    import threading
    import queue
    def worker(q):q.put("Hello from worker")
    if __name__ == "__main__":q = queue.Queue()t = threading.Thread(target=worker, args=(q,))t.start()t.join()print(q.get())
    

Golang

  • 语法:使用 channel
    package main
    import "fmt"
    func worker(ch chan string) {ch <- "Hello from worker"
    }
    func main() {ch := make(chan string)go worker(ch)fmt.Println(<-ch)
    }
    

4. 什么是互斥锁?

  • 互斥锁(Mutex) 是一种同步机制,用于防止多个线程同时访问共享资源。
  • 当一个线程持有锁时,其他线程必须等待锁释放后才能访问共享资源。

5. 使用互斥锁

Python

  • 语法:使用 threading.Lock
    import threading
    counter = 0
    lock = threading.Lock()
    def worker():global counterwith lock:counter += 1
    if __name__ == "__main__":threads = []for _ in range(10):t = threading.Thread(target=worker)threads.append(t)t.start()for t in threads:t.join()print("Counter:", counter)
    

Golang

  • 语法:使用 sync.Mutex
    package main
    import ("fmt""sync"
    )
    var (counter intlock    sync.Mutex
    )
    func worker(wg *sync.WaitGroup) {defer wg.Done()lock.Lock()counter++lock.Unlock()
    }
    func main() {var wg sync.WaitGroupfor i := 0; i < 10; i++ {wg.Add(1)go worker(&wg)}wg.Wait()fmt.Println("Counter:", counter)
    }
    

6. 多线程死锁以及解决方案

什么是死锁?

  • 死锁 是指多个线程互相等待对方释放锁,导致所有线程都无法继续执行。
  • 死锁的四个必要条件
    1. 互斥条件:资源一次只能被一个线程占用。
    2. 占有并等待:线程持有资源并等待其他资源。
    3. 不可抢占:资源只能由持有它的线程释放。
    4. 循环等待:线程之间形成循环等待资源的关系。

解决方案

  1. 避免嵌套锁:尽量减少锁的嵌套使用。
  2. 按顺序加锁:所有线程按相同的顺序获取锁。
  3. 使用超时机制:为锁设置超时时间,避免无限等待。
  4. 使用死锁检测工具:如 Python 的 threading 模块或 Golang 的 pprof 工具。

7. 线程需要注意的点

  1. 线程安全
    • 确保共享资源的访问是线程安全的,使用锁或其他同步机制。
  2. 资源竞争
    • 避免多个线程同时修改同一数据,导致数据不一致。
  3. 性能开销
    • 线程的创建和切换有一定开销,避免创建过多线程。
  4. 死锁和活锁
    • 避免死锁和活锁(线程不断重试但无法取得进展)。
  5. 线程间通信
    • 使用队列、管道或共享内存等方式实现线程间通信。
  6. 全局解释器锁(GIL)
    • 在 Python 中,GIL 限制了多线程的并行执行,建议使用多进程或异步编程提高性能。

示例

Python

import threading
import queue
counter = 0
lock = threading.Lock()
def worker(q):global counterwith lock:counter += 1q.put(f"Worker {threading.current_thread().name} is done")
if __name__ == "__main__":q = queue.Queue()threads = []for i in range(3):t = threading.Thread(target=worker, args=(q,))threads.append(t)t.start()for t in threads:t.join()while not q.empty():print(q.get())print("Counter:", counter)

Golang

package main
import ("fmt""sync"
)
var (counter intlock    sync.Mutex
)
func worker(wg *sync.WaitGroup, ch chan string) {defer wg.Done()lock.Lock()counter++lock.Unlock()ch <- "Worker is done"
}
func main() {var wg sync.WaitGroupch := make(chan string, 3)for i := 0; i < 3; i++ {wg.Add(1)go worker(&wg, ch)}wg.Wait()close(ch)for msg := range ch {fmt.Println(msg)}fmt.Println("Counter:", counter)
}

异常处理

1. 什么是异常?

  • 异常 是程序执行过程中发生的错误或意外情况,它会中断程序的正常流程。
  • 异常通常由以下原因引起:
    • 代码逻辑错误(如除以零、访问不存在的索引)。
    • 外部因素(如文件不存在、网络连接失败)。
    • 用户输入错误(如输入格式不正确)。
  • 异常处理是捕获并处理这些错误,使程序能够继续运行或优雅地退出。

2. 异常处理语句

Python

  • 语法:使用 try-except-finally
    try:# 可能引发异常的代码result = 10 / 0
    except ZeroDivisionError as e:# 捕获特定异常print(f"Error: {e}")
    except Exception as e:# 捕获所有异常print(f"Unexpected error: {e}")
    else:# 没有异常时执行print("No error occurred")
    finally:# 无论是否发生异常都会执行print("Cleanup code")
    
  • 特点
    • try:包含可能引发异常的代码。
    • except:捕获并处理异常。
    • else:没有异常时执行。
    • finally:无论是否发生异常都会执行。

Golang

  • 语法:使用 deferpanicrecover
    package main
    import "fmt"
    func main() {defer func() {if r := recover(); r != nil {fmt.Println("Recovered from panic:", r)}}()// 可能引发 panic 的代码panic("Something went wrong")
    }
    
  • 特点
    • panic:引发异常。
    • recover:捕获异常。
    • defer:延迟执行,通常用于资源清理。

Shell

  • 语法:使用 trap 捕获信号或错误。
    #!/bin/bash
    trap "echo 'Error occurred'; exit 1" ERR
    # 可能引发错误的代码
    ls /nonexistent
    
  • 特点
    • trap:捕获信号或错误并执行指定命令。
    • ERR:捕获命令执行失败的错误。

3. 异常处理的最佳实践

  1. 捕获特定异常
    • 尽量捕获特定异常,而不是捕获所有异常,以便更好地处理问题。
  2. 资源清理
    • 使用 finally(Python)或 defer(Golang)确保资源被正确释放。
  3. 日志记录
    • 在捕获异常时记录日志,便于调试和排查问题。
  4. 避免滥用异常
    • 不要使用异常处理控制正常流程,异常应仅用于处理意外情况。
  5. 用户友好提示
    • 在捕获异常时向用户提供清晰友好的错误信息。

示例

Python

try:result = 10 / 0
except ZeroDivisionError as e:print(f"Error: {e}")
except Exception as e:print(f"Unexpected error: {e}")
else:print("No error occurred")
finally:print("Cleanup code")

Golang

package main
import "fmt"
func main() {defer func() {if r := recover(); r != nil {fmt.Println("Recovered from panic:", r)}}()panic("Something went wrong")
}

Shell

#!/bin/bash
trap "echo 'Error occurred'; exit 1" ERR
ls /nonexistent

对比总结

特性 Python Golang Shell
异常处理语句 try-except-finally defer, panic, recover trap
捕获特定异常 except recover trap
资源清理 finally defer trap
异常引发 raise panic exit
用户友好提示 支持 支持 支持

Docker自动化调用

1. Docker API 的种类与启用

种类

  1. Docker Engine API
    • 用于与 Docker 守护进程交互,支持容器、镜像、网络等操作。
    • 默认端口:2375(HTTP)或 2376(HTTPS)。
  2. Docker Registry API
    • 用于与 Docker 镜像仓库交互,支持镜像的上传、下载、删除等操作。
    • 默认端口:5000(HTTP)或 5001(HTTPS)。

启用

  • 启用 Docker Engine API
    1. 修改 Docker 配置文件(如 /etc/docker/daemon.json):
      {"hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2375"]
      }
      
    2. 重启 Docker 服务:
      sudo systemctl restart docker
      
  • 启用 Docker Registry API
    1. 启动 Docker Registry 容器:
      docker run -d -p 5000:5000 --name registry registry:2
      
    2. 使用 HTTPS 时,配置 TLS 证书。

2. 操作镜像

使用 Docker Engine API

  • 拉取镜像
    curl -X POST "http://localhost:2375/images/create?fromImage=nginx&tag=latest"
    
  • 列出镜像
    curl "http://localhost:2375/images/json"
    
  • 删除镜像
    curl -X DELETE "http://localhost:2375/images/nginx:latest"
    

使用 Docker Registry API

  • 列出镜像标签
    curl "http://localhost:5000/v2/nginx/tags/list"
    
  • 删除镜像
    curl -X DELETE "http://localhost:5000/v2/nginx/manifests/<digest>"
    

3. 操作容器

使用 Docker Engine API

  • 创建容器
    curl -X POST "http://localhost:2375/containers/create" \-H "Content-Type: application/json" \-d '{"Image": "nginx", "HostConfig": {"PortBindings": {"80/tcp": [{"HostPort": "8080"}]}}}'
    
  • 启动容器
    curl -X POST "http://localhost:2375/containers/<container_id>/start"
    
  • 停止容器
    curl -X POST "http://localhost:2375/containers/<container_id>/stop"
    
  • 删除容器
    curl -X DELETE "http://localhost:2375/containers/<container_id>"
    

4. 客户端和服务端的 TLS 认证

生成证书

  1. 生成 CA 证书
    openssl genrsa -aes256 -out ca-key.pem 4096
    openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem
    
  2. 生成服务器证书
    openssl genrsa -out server-key.pem 4096
    openssl req -subj "/CN=<server_ip>" -sha256 -new -key server-key.pem -out server.csr
    echo subjectAltName = IP:<server_ip>,IP:127.0.0.1 > extfile.cnf
    openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile extfile.cnf
    
  3. 生成客户端证书
    openssl genrsa -out client-key.pem 4096
    openssl req -subj "/CN=client" -new -key client-key.pem -out client.csr
    echo extendedKeyUsage = clientAuth > extfile.cnf
    openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out client-cert.pem -extfile extfile.cnf
    

配置 Docker 守护进程

  1. 修改 Docker 配置文件(如 /etc/docker/daemon.json):
    {"tlsverify": true,"tlscacert": "/path/to/ca.pem","tlscert": "/path/to/server-cert.pem","tlskey": "/path/to/server-key.pem","hosts": ["tcp://0.0.0.0:2376"]
    }
    
  2. 重启 Docker 服务:
    sudo systemctl restart docker
    

客户端使用 TLS 认证

  • 使用 curl
    curl --cert /path/to/client-cert.pem --key /path/to/client-key.pem --cacert /path/to/ca.pem https://<server_ip>:2376/version
    
  • 使用 docker 客户端
    docker --tlsverify --tlscacert=/path/to/ca.pem --tlscert=/path/to/client-cert.pem --tlskey=/path/to/client-key.pem -H=<server_ip>:2376 version
    

5. 自动化

使用 Python

  • 安装 Docker SDK
    pip install docker
    
  • 示例代码
    import docker
    client = docker.DockerClient(base_url='tcp://localhost:2376', tls=True)
    # 拉取镜像
    client.images.pull('nginx')
    # 创建容器
    container = client.containers.run('nginx', detach=True, ports={'80/tcp': 8080})
    # 启动容器
    container.start()
    # 停止容器
    container.stop()
    # 删除容器
    container.remove()
    

使用 Golang

  • 安装 Docker SDK
    go get github.com/docker/docker/client
    
  • 示例代码
    package main
    import ("context""fmt""github.com/docker/docker/api/types""github.com/docker/docker/client"
    )
    func main() {cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())if err != nil {panic(err)}// 拉取镜像_, err = cli.ImagePull(context.Background(), "nginx", types.ImagePullOptions{})if err != nil {panic(err)}// 创建容器resp, err := cli.ContainerCreate(context.Background(), &container.Config{Image: "nginx",}, &container.HostConfig{PortBindings: map[nat.Port][]nat.PortBinding{"80/tcp": {{HostPort: "8080"}},},}, nil, nil, "")if err != nil {panic(err)}// 启动容器if err := cli.ContainerStart(context.Background(), resp.ID, types.ContainerStartOptions{}); err != nil {panic(err)}// 停止容器if err := cli.ContainerStop(context.Background(), resp.ID, nil); err != nil {panic(err)}// 删除容器if err := cli.ContainerRemove(context.Background(), resp.ID, types.ContainerRemoveOptions{}); err != nil {panic(err)}
    }
    

镜像和容器的增删查改

1. 操作镜像

查看镜像

  • API 端点GET /images/json
  • 示例
    curl "http://localhost:2375/images/json"
    
  • 返回结果
    [{"Id": "sha256:...","RepoTags": ["nginx:latest"],"Size": 1337,"Created": 1633036800}
    ]
    

下载镜像

  • API 端点POST /images/create
  • 示例
    curl -X POST "http://localhost:2375/images/create?fromImage=nginx&tag=latest"
    
  • 返回结果
    {"status":"Pulling from library/nginx","id":"latest"}
    

删除镜像

  • API 端点DELETE /images/{name}
  • 示例
    curl -X DELETE "http://localhost:2375/images/nginx:latest"
    
  • 返回结果
    [{"Deleted":"sha256:..."}]
    

2. 操作容器

创建容器

  • API 端点POST /containers/create
  • 示例
    curl -X POST "http://localhost:2375/containers/create" \-H "Content-Type: application/json" \-d '{"Image": "nginx", "HostConfig": {"PortBindings": {"80/tcp": [{"HostPort": "8080"}]}}}'
    
  • 返回结果
    {"Id":"...","Warnings":[]}
    

查看容器

  • API 端点GET /containers/json
  • 示例
    curl "http://localhost:2375/containers/json"
    
  • 返回结果
    [{"Id": "...","Names": ["/my_container"],"Image": "nginx","Status": "Up 5 minutes"}
    ]
    

启动容器

  • API 端点POST /containers/{id}/start
  • 示例
    curl -X POST "http://localhost:2375/containers/<container_id>/start"
    
  • 返回结果
    (无返回内容)
    

停止容器

  • API 端点POST /containers/{id}/stop
  • 示例
    curl -X POST "http://localhost:2375/containers/<container_id>/stop"
    
  • 返回结果
    (无返回内容)
    

删除容器

  • API 端点DELETE /containers/{id}
  • 示例
    curl -X DELETE "http://localhost:2375/containers/<container_id>"
    
  • 返回结果
    (无返回内容)
    

3. 使用 Docker SDK

Python

  • 安装 Docker SDK
    pip install docker
    
  • 示例代码
    import docker
    client = docker.DockerClient(base_url='tcp://localhost:2375')
    # 查看镜像
    images = client.images.list()
    for image in images:print(image.tags)
    # 下载镜像
    client.images.pull('nginx')
    # 删除镜像
    client.images.remove('nginx:latest')
    # 创建容器
    container = client.containers.create('nginx', detach=True, ports={'80/tcp': 8080})
    # 查看容器
    containers = client.containers.list()
    for container in containers:print(container.name)
    # 启动容器
    container.start()
    # 停止容器
    container.stop()
    # 删除容器
    container.remove()
    

Golang

  • 安装 Docker SDK
    go get github.com/docker/docker/client
    
  • 示例代码
    package main
    import ("context""fmt""github.com/docker/docker/api/types""github.com/docker/docker/client"
    )
    func main() {cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())if err != nil {panic(err)}// 查看镜像images, err := cli.ImageList(context.Background(), types.ImageListOptions{})if err != nil {panic(err)}for _, image := range images {fmt.Println(image.RepoTags)}// 下载镜像_, err = cli.ImagePull(context.Background(), "nginx", types.ImagePullOptions{})if err != nil {panic(err)}// 删除镜像_, err = cli.ImageRemove(context.Background(), "nginx:latest", types.ImageRemoveOptions{})if err != nil {panic(err)}// 创建容器resp, err := cli.ContainerCreate(context.Background(), &container.Config{Image: "nginx",}, &container.HostConfig{PortBindings: map[nat.Port][]nat.PortBinding{"80/tcp": {{HostPort: "8080"}},},}, nil, nil, "")if err != nil {panic(err)}// 查看容器containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{})if err != nil {panic(err)}for _, container := range containers {fmt.Println(container.Names)}// 启动容器if err := cli.ContainerStart(context.Background(), resp.ID, types.ContainerStartOptions{}); err != nil {panic(err)}// 停止容器if err := cli.ContainerStop(context.Background(), resp.ID, nil); err != nil {panic(err)}// 删除容器if err := cli.ContainerRemove(context.Background(), resp.ID, types.ContainerRemoveOptions{}); err != nil {panic(err)}
    }
    

对比总结

操作 API 端点 Python SDK Golang SDK
查看镜像 GET /images/json client.images.list() cli.ImageList()
下载镜像 POST /images/create client.images.pull() cli.ImagePull()
删除镜像 DELETE /images/{name} client.images.remove() cli.ImageRemove()
创建容器 POST /containers/create client.containers.create() cli.ContainerCreate()
查看容器 GET /containers/json client.containers.list() cli.ContainerList()
启动容器 POST /containers/{id}/start container.start() cli.ContainerStart()
停止容器 POST /containers/{id}/stop container.stop() cli.ContainerStop()
删除容器 DELETE /containers/{id} container.remove() cli.ContainerRemove()

Docker 系统管理开发

1. 系统信息获取

获取 Docker 版本信息

  • API 端点GET /version
  • 示例
    curl "http://localhost:2375/version"
    
  • 返回结果
    {"Version": "20.10.7","ApiVersion": "1.41","MinAPIVersion": "1.12","GitCommit": "b0f5bc3","GoVersion": "go1.13.15","Os": "linux","Arch": "amd64"
    }
    

获取 Docker 系统信息

  • API 端点GET /info
  • 示例
    curl "http://localhost:2375/info"
    
  • 返回结果
    {"Containers": 10,"Images": 20,"Driver": "overlay2","KernelVersion": "5.4.0-80-generic","OperatingSystem": "Ubuntu 20.04.2 LTS","NCPU": 4,"MemTotal": 16777216000
    }
    

2. 资源监控

获取容器资源使用情况

  • API 端点GET /containers/{id}/stats
  • 示例
    curl "http://localhost:2375/containers/<container_id>/stats"
    
  • 返回结果
    {"cpu_stats": {"cpu_usage": {"total_usage": 123456789}},"memory_stats": {"usage": 104857600}
    }
    

获取系统资源使用情况

  • API 端点GET /system/df
  • 示例
    curl "http://localhost:2375/system/df"
    
  • 返回结果
    {"LayersSize": 123456789,"Images": 20,"Containers": 10,"Volumes": 5
    }
    

3. 日志管理

获取容器日志

  • API 端点GET /containers/{id}/logs
  • 示例
    curl "http://localhost:2375/containers/<container_id>/logs"
    
  • 返回结果
    (容器日志内容)
    

配置日志驱动

  • API 端点POST /containers/create
  • 示例
    curl -X POST "http://localhost:2375/containers/create" \-H "Content-Type: application/json" \-d '{"Image": "nginx", "HostConfig": {"LogConfig": {"Type": "json-file", "Config": {"max-size": "10m", "max-file": "3"}}}}'
    

4. 网络管理

列出网络

  • API 端点GET /networks
  • 示例
    curl "http://localhost:2375/networks"
    
  • 返回结果
    [{"Id": "...","Name": "bridge","Driver": "bridge","Scope": "local"}
    ]
    

创建网络

  • API 端点POST /networks/create
  • 示例
    curl -X POST "http://localhost:2375/networks/create" \-H "Content-Type: application/json" \-d '{"Name": "my_network", "Driver": "bridge"}'
    
  • 返回结果
    {"Id":"...","Warnings":[]}
    

删除网络

  • API 端点DELETE /networks/{id}
  • 示例
    curl -X DELETE "http://localhost:2375/networks/<network_id>"
    

5. 存储管理

列出卷

  • API 端点GET /volumes
  • 示例
    curl "http://localhost:2375/volumes"
    
  • 返回结果
    {"Volumes": [{"Name": "my_volume","Driver": "local","Mountpoint": "/var/lib/docker/volumes/my_volume/_data"}]
    }
    

创建卷

  • API 端点POST /volumes/create
  • 示例
    curl -X POST "http://localhost:2375/volumes/create" \-H "Content-Type: application/json" \-d '{"Name": "my_volume", "Driver": "local"}'
    
  • 返回结果
    {"Name":"my_volume","Driver":"local","Mountpoint":"/var/lib/docker/volumes/my_volume/_data"}
    

删除卷

  • API 端点DELETE /volumes/{name}
  • 示例
    curl -X DELETE "http://localhost:2375/volumes/my_volume"
    

6. 使用 Docker SDK

Python

  • 安装 Docker SDK
    pip install docker
    
  • 示例代码
    import docker
    client = docker.DockerClient(base_url='tcp://localhost:2375')
    # 获取 Docker 版本信息
    print(client.version())
    # 获取 Docker 系统信息
    print(client.info())
    # 获取容器资源使用情况
    stats = client.containers.get('<container_id>').stats(stream=False)
    print(stats)
    # 获取容器日志
    logs = client.containers.get('<container_id>').logs()
    print(logs)
    # 创建网络
    network = client.networks.create("my_network", driver="bridge")
    print(network.id)
    # 创建卷
    volume = client.volumes.create(name="my_volume", driver="local")
    print(volume.name)
    

Golang

  • 安装 Docker SDK
    go get github.com/docker/docker/client
    
  • 示例代码
    package main
    import ("context""fmt""github.com/docker/docker/api/types""github.com/docker/docker/client"
    )
    func main() {cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())if err != nil {panic(err)}// 获取 Docker 版本信息version, err := cli.ServerVersion(context.Background())if err != nil {panic(err)}fmt.Println(version.Version)// 获取 Docker 系统信息info, err := cli.Info(context.Background())if err != nil {panic(err)}fmt.Println(info.Containers)// 获取容器资源使用情况stats, err := cli.ContainerStats(context.Background(), "<container_id>", false)if err != nil {panic(err)}fmt.Println(stats)// 获取容器日志logs, err := cli.ContainerLogs(context.Background(), "<container_id>", types.ContainerLogsOptions{})if err != nil {panic(err)}fmt.Println(logs)// 创建网络network, err := cli.NetworkCreate(context.Background(), "my_network", types.NetworkCreate{Driver: "bridge",})if err != nil {panic(err)}fmt.Println(network.ID)// 创建卷volume, err := cli.VolumeCreate(context.Background(), types.VolumeCreateRequest{Name:   "my_volume",Driver: "local",})if err != nil {panic(err)}fmt.Println(volume.Name)
    }
    

对比总结

操作 API 端点 Python SDK Golang SDK
获取版本信息 GET /version client.version() cli.ServerVersion()
获取系统信息 GET /info client.info() cli.Info()
获取容器资源使用 GET /containers/{id}/stats container.stats() cli.ContainerStats()
获取容器日志 GET /containers/{id}/logs container.logs() cli.ContainerLogs()
创建网络 POST /networks/create client.networks.create() cli.NetworkCreate()
创建卷 POST /volumes/create client.volumes.create() cli.VolumeCreate()

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

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

相关文章

从ClickHouse中流式查询大数据

提示:本篇不适合手机阅读,主要为了提供代码实现。为了减速少大的Excel文件在内存中驻留,使用流的方式,边查询边组装,边下载文件相对来说是一个好的方式,下面是基于ClickHouse数据源的方式,下载100万条记录的处理方式,本地测试,内存只有100多M的使用,下载完后就会释放…

Axure9下载完美汉化及破解

一)Axure9下载 复制链接到浏览器,复制后需删除作者后面的部份才能打开!Windows系统: https://pan.baidu.com/s/1CF-lpmzzaevUX2lCZUmmiAMac新系统(M芯片) https://pan.baidu.com/s/1k73IJBAdlwUL1YPPRWXchA 提取码: 1323 注:M1版本自带破解,仅需汉化即可Mac旧系统(int…

单视图度量(Single View Metrology)总结

前面我们介绍了标定相机,并且我们知道,如果我们能够确定三维点的坐标以及标定相机的参数,就能够确定它在图像平面的位置。那我们现在思考一个问题,如果我们知道图像平面的坐标以及标定相机的参数,我们能够确定这个三维点的位置吗? 答案是否定的。因为一般情况下,三维点可…

简说VS中的.http

在VS17.5中,加入了一个.http文件,应该和你想的一样,就是一个存放请求的文件,关键是他能执行请求,很像curl。不过市面上相似的工具有很多,比如Postman就做的很好了,那为什么VS还要引入呢?我的简单理解,虽然Postman好用,但毕竟和VS中的源码是分离的,即使Postman等工具…

P1119 灾后重建

链接 https://www.luogu.com.cn/problem/P1119 题目知识点floyd算法思路看题解,讲的差不多,本篇就是记录下写过的题。 唯一要注意的就是当遍历k(本代码用cnt代替)时,ij都要从0取到n-1。代码 #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<algorithm&g…

库卡机器人维修伺服电机刹车故障维修

库卡机器人作为工业自动化领域的佼佼者,其伺服电机系统的稳定性和可靠性对于生产线的顺畅运行至关重要。然而,在实际应用中,KUKA工业机械手伺服电机刹车故障时有发生,这不仅会影响机器人的正常运行,还可能对生产安全造成威胁。 ,kuka机器人电机刹车故障通常表现为以下几种…

市场上的各种指数

上证指数系列 由上海证券交易所编制,重点指数如下(数据截至2024-07-06):指数名称 指数代码 收盘 成交额(亿元) 平均股本(亿股) 静态市盈率上证指数 000001 2976.3 2793.62 21.37 12.74科创50 000688 732.06 223.94 16.28 28.55上证180 000010 7754.99 1184.8 145.84 11.24上…

lesson-9-a-story-on-cyclic-imports

前言 模块(Module)是我们用来组织 Python 代码的基本单位。很多功能强大的复杂站点,都由成百上千个独立模块共同组成。 虽然模块有着不可替代的用处,但它有时也会给我们带来麻烦。比如,当你接手一个新项目后,刚展开项目目录。第一眼就看到了攀枝错节、难以理解的模块结构…

KUKA库卡机器人KRC5控制器维修全过程

库卡工业机器人作为现代工业中的重要设备,KUKA机械手KRC5控制柜作为其核心部件,对机器人的正常运行起着至关重要的作用。 【一】KUKA机械手KRC5控制柜的结构分析 库卡工业机器人控制柜主要由电源模块、控制模块、驱动模块、传感器模块等组成。这些模块协同工作,确保机器人的…

萌新刚入坑

markdddown学习 标题 三级标题 四级标题 字体 Hello,World! Hello,World! Hello,World! Hello,World! 引用 选择狂神说java,走上人生巅峰 分割线图片超链接 点击跳转到狂神博客 列表A CABC表格名字 性别 生日张三 男 1997.1.1代码 hello public

Retrieval-Augmented Generation

大模型的商业化落地挑战 更好地控制大模型生成:生成优点:内容的多样性、创造性 缺点:存在不可控制的问题检索优点:可控 缺点:内容具有局限性结合两者:检索增强生成(Retrieval-Augmented Generation, RAG) 案例:金融智能客服系统的几种思路专家系统 生成式模型 大模型检索…

沁恒CH32V307EVT-R1开发板使用说明

首先下载官方的资料:CH32V307EVT.ZIP - 南京沁恒微电子股份有限公司 解压后CH32V307EVT\EVT\EXAM里的就是官方的示例代码,CH32V307EVT\EVT\PUB下面的是文档 CH32V307EVT/EVT/PUB/CH32V30x评估板说明书.pdf:是各个开发板的介绍 CH32V307EVT/EVT/PUB/CH32V30xSCH.pdf:是开发板…