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

news2024/11/16 1:19:23

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.sh

echo "$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.py

import 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.py

with 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/bash

PHONEBOOK_ENTRIES="bash_phonebook_entries"


if [ "$#" -lt 1 ]; then
    exit 1

elif [ "$1" = "new" ]; then
    # YOUR CODE HERE #

elif [ "$1" = "list" ]; then
    if [ ! -e $PHONEBOOK_ENTRIES ] || [ ! -s $PHONEBOOK_ENTRIES ]; then
        echo "phonebook is empty"
    else
        # YOUR CODE HERE #
    fi

elif [ "$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 python

import sys
import os

PHONEBOOK_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/bash

PHONEBOOK_ENTRIES="bash_phonebook_entries"

if [ "$#" -lt 1 ]; then
    exit 1

elif [ "$1" = "new" ]; then
    if [ "$#" -ne 3 ]; then
        echo "Usage: $0 new <name> <number>"
        exit 1
    fi
    echo "$2 $3" >> "$PHONEBOOK_ENTRIES"
    echo "Added: $2 $3"

elif [ "$1" = "list" ]; then
    if [ ! -e "$PHONEBOOK_ENTRIES" ] || [ ! -s "$PHONEBOOK_ENTRIES" ]; then
        echo "phonebook is empty"
    else
        cat "$PHONEBOOK_ENTRIES"
    fi

elif [ "$1" = "lookup" ]; then
    if [ "$#" -ne 2 ]; then
        echo "Usage: $0 lookup <name>"
        exit 1
    fi
    if grep -q "$2" "$PHONEBOOK_ENTRIES"; then
        grep "$2" "$PHONEBOOK_ENTRIES" | awk '{print $2}'
    else
        echo "No entry found for $2"
    fi

elif [ "$1" = "remove" ]; then
    if [ "$#" -ne 2 ]; then
        echo "Usage: $0 remove <name>"
        exit 1
    fi
    if grep -q "$2" "$PHONEBOOK_ENTRIES"; then
     	# 取出内容放入temp后再通过mv覆盖原文件
        grep -v "$2" "$PHONEBOOK_ENTRIES" > temp && mv temp "$PHONEBOOK_ENTRIES" 
        echo "Removed all entries for $2"
    else
        echo "No entry found for $2"
    fi
elif [ "$1" = "clear" ]; then
    > "$PHONEBOOK_ENTRIES"
    echo "Phonebook cleared"

else
    echo "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 python

import sys
import os

PHONEBOOK_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 = False
        with 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 = True
        if 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 = False
        with 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 = True
        if 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 ];then
	echo "nice"
else
	echo "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 可以跨平台运行。

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

半导体PEEK纳米级钻孔,用德国高精密主轴

在半导体行业&#xff0c;对精度、效率与稳定性的要求近乎苛刻。其中&#xff0c;PEEK&#xff08;聚醚醚酮&#xff09;材料因其优异的耐热性、耐化学性和机械性能&#xff0c;在高端半导体封装、微流控芯片等领域得到了广泛应用。然而&#xff0c;PEEK材料的硬度与韧性并存&a…

Armv8/Armv9的Pstate寄存器介绍

PSTATE概述 在Armv7及其之前&#xff0c;有一个重要的寄存器叫做程序状态寄存器CPSR&#xff0c;但是到了Armv8/Armv9的aarch64架构时&#xff0c;删除了CPSR寄存器&#xff0c;改为了PSTATE&#xff08;PE状态寄存器&#xff09;。 PSTATE表示一组小寄存器的集合&#xff0c;…

隐私指纹浏览器产品系列 — 什么是指纹(一)

1.引言 现在许多网站在努力的尝试标记互联网上的每一个访客&#xff0c;用以追踪用户的行为轨迹&#xff0c;分析行为习惯&#xff0c;以及确认是否为真实用户。除此之外&#xff0c;他们还利用这些标记&#xff0c;将多个可能是同一个用户身份的访客进行归一&#xff0c;关联…

中国高尔夫运动快速发展中,深圳高尔夫展邀您迎接机遇与挑战

在浩瀚的体育世界中&#xff0c;高尔夫以其悠久的历史、优雅的姿态和独特的魅力闻名于世&#xff0c;被誉为“古老的贵族运动”&#xff0c;而这个美誉却让很多人对它敬而远之。其实高尔夫被称作“贵族运动”&#xff0c;仅仅是因为早期它更多在贵族之间流行而已。 高尔夫&…

【TS】基本类型

基本类型 类型例子描述number1, -33, 2.5任意数字stringhi, "hi", hi任意字符串booleantrue、false布尔值true或false字面量其本身限制变量的值就是该字面量的值any*任意类型unknown*类型安全的anyvoid空值&#xff08;undefined&#xff09;没有值&#xff08;或und…

鸿蒙HarmonyOS开发:如何使用第三方库,加速应用开发

文章目录 一、如何安装 ohpm-cli二、如何安装三方库1、在 oh-package.json5 文件中声明三方库&#xff0c;以 ohos/crypto-js 为例&#xff1a;2、安装指定名称 pacakge_name 的三方库&#xff0c;执行以下命令&#xff0c;将自动在当前目录下的 oh-package.json5 文件中自动添…

面对电商渠道品牌要如何控价

在当今竞争激烈的市场环境中&#xff0c;品牌销售渠道的管理至关重要。线上和线下渠道的低价、窜货问题犹如侵蚀品牌根基的蚁穴&#xff0c;若不加以有效治理&#xff0c;品牌价值将受到严重损害。 线上渠道方面&#xff0c;除了利用系统精准监测低价情况外&#xff0c;还应注重…

手撕数据结构之二叉树

1.树 树的基本概念与结构 树是⼀种⾮线性的数据结构&#xff0c;它是由 n&#xff08;n>0&#xff09; 个有限结点组成⼀个具有层次关系的集合。把它叫做树是因为它看起来像⼀棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;⽽叶朝下的。 • 有⼀个特殊的结点&…

python语言day2

字符串&#xff1a; 字符串的方法 字符串格式化&#xff1a; 输出结果&#xff1a; 姓名张三今年123岁&#xff0c;现在在北京工作,名字叫张三 text "姓名{0}今年{1}岁&#xff0c;现在在{2}工作,名字叫{0}".format("张三",123,"北京") print(t…

关于冒泡算法

一、前言 当谈及经典排序算法时&#xff0c;冒泡排序&#xff08;Bubble Sort&#xff09;无疑是最具代表性的一种。这种算法以其简单直观的特点&#xff0c;成为初学者理解排序基本概念的理想选择。本文将深入解析冒泡排序的原理、实现步骤&#xff0c;以及其在 C# 编程中的具…

【Vue】RuoYi-Vue 若依 vue3 版本安装 tailwindcss 不生效问题

解决方法 删除默认安装教程下的 postcss.config.js 将配置转移到 vite.config.js 中&#xff0c;不生效原因我推测是因为 vite.config.js 配置 postcss 这段覆盖了 postcss.config.js 所致 代码修改如下&#xff1a; 另外原博主友情提示&#xff0c;引入的TailwindCSS的样式…

已解决AttributeError: module ‘emoji‘ has no attribute ‘get_emoji_regexp‘

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

遥感技术在生态系统碳储量、碳收支、碳循环以及人为源排放反演等领域的技术发展

卫星遥感具有客观、连续、稳定、大范围、重复观测的优点&#xff0c;已成为监测全球碳盘查不可或缺的技术手段&#xff0c;卫星遥感也正在成为新一代 、国际认可的全球碳核查方法。目的就是梳理碳中和与碳达峰对卫星遥感的现实需求&#xff0c;系统总结遥感技术在生态系统碳储量…

synchronized 与 Lock 的区别

synchronized 与 Lock 的区别 1、相同点2、不同点2.1 精确性与灵活性2.2 性能2.3 使用便利性 3、示例3.1 synchronized 示例3.2 Lock 示例 4、总结 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在Java多线程编程中&#xff0c;synchroniz…

查找并可视化非线性关系

使用部分依赖图 (PDP)、互信息和特征重要性分析非线性关系 刚开始开车时&#xff0c;你的经验较少&#xff0c;有时还会比较鲁莽。随着年龄的增长&#xff0c;你会获得更多的经验&#xff08;和意识&#xff09;&#xff0c;发生事故的可能性也会降低。然而&#xff0c;这种趋势…

Java语言程序设计基础篇_编程练习题*16.6 (演示TextField的属性)

目录 题目&#xff1a;*16.6 (演示TextField的属性) 习题思路 代码示例 结果展示 题目&#xff1a;*16.6 (演示TextField的属性) 编写一个程序&#xff0c;动态地设置文本域的水平对齐属性和列宽属性&#xff0c;如图16-38a所示 习题思路 创建一个HBox&#xff0c;一个Labe…

【前端】记录各种控制台警告/bug

一、Element Plus 1、控制台警告&#xff1a;“Runtime directive used on component with non-element root node. The directives will not function as intended.” 错误原因&#xff1a;在 Vue 组件上使用了运行时指令&#xff08;指那些在运行时动态绑定到 DOM 元素上的指…

bilibili实习生一面0625

OSI七层模型 物理层&#xff1a;将帧中的比特传送到下一个节点&#xff08;比特&#xff09; 数据链路层&#xff1a;将数据包装成帧并传送到路径上下一个节点&#xff0c;将相邻节点间不可靠的物理链路变成可靠的逻辑链路&#xff08;帧&#xff09; 网络层&#xff1a;路由寻…

信创数据库沙龙(深圳站 | 开启报名)

信创数据库沙龙: 是一个致力于推动数据库技术创新和发展的高端交流平台&#xff0c;旨在增强国内数据库产业的自主可控性和高质量发展。这个平台汇集了学术界和产业界的顶尖专家、学者以及技术爱好者&#xff0c;通过专题演讲、案例分享和技术研讨等丰富多样的活动形式&#x…

Tkinter Canvas 如何在顶部绘制文本?

在 Tkinter 的 Canvas 上绘制文本非常简单&#xff0c;我们可以使用 create_text 方法来完成这个任务。create_text 方法允许我们指定文本的位置、内容以及字体等属性。为了确保文本绘制在顶部&#xff0c;我们可以设置 y 坐标接近 Canvas 的顶部。 1、问题背景 在使用 Tkinte…