Shell脚本基础 以及 变量和引用

目录

Shell脚本基础

Shell的基本元素

Shell脚本规范

Shell脚本编写方式

交互式执行

作为程序文件执行

Shell脚本执行方式

bash for_test.sh

sh for_test.sh

./for_test.sh

source for_test.sh

Shell退出状态

变量和引用

什么是变量

变量的命名

变量的作用范围

局部变量

全局变量

删除变量

变量的类型

自定义变量

格式

查看变量的值

对于单引号和双引号的区别

使用 declare 来定义变量

通过交互定义变量

环境变量

只读变量

位置变量

特殊变量

$* 和 $@的区别

$?执行结果状态

特殊状态变量

变量的特殊用法

获取变量

变量值截取

字符串删除

字符串替换

删除文件名


Shell脚本基础

Shell的基本元素

声明:

        使用哪一种解释器来解释并且执行当前的脚本        #!/bin/bash

命令:

        可以执行的语句,实现程序的功能

注释:

        单行注释,使用 # 来进行注释,另一种是多行注释 :<<BLOCK        注释内容是 BLOCK

赋予脚本可执行权限

Shell脚本规范

脚本名称尽量做到见名知意
在脚本的开头指定解释器
在开头增加版权信息

尽量使用系统命令,而少使用管道 

尽量不要使用中文注释
代码注重缩进

Shell脚本编写方式

交互式执行

[root@openEuler ~]# for name in `ls /etc`
> do
> echo $name
> done

作为程序文件执行

[root@openEuler ~]# vim for_test.sh#!/bin/bashecho $USER

Shell脚本执行方式

bash for_test.sh

        会产生一个子Shell,然后在子Shell中运行脚本,执行完后回去父Shell

sh for_test.sh

        也会产生一个子Shell,然后在子Shell中运行脚本,执行完成后回去父Shell

./for_test.sh

        也会产生一个子Shell,不同点在于它需要有 x 权限

source for_test.sh

        作用与 .  执行一样

示例:

[root@openEuler ~]# sh for_test.sh 
root
[root@openEuler ~]# ll
total 32
-rw-------. 1 root root  881 Mar 16 20:10 anaconda-ks.cfg
drwxr-xr-x. 2 root root 4096 Mar 17 10:29 d1
-rw-r--r--. 1 root root   24 Mar 23 14:32 for_test.sh
-rw-r--r--. 1 root root   49 Mar 16 21:07 hehe.txt
-rw-r--r--. 1 root root   35 Mar 17 09:51 message.txt
-rwxr-xr-x. 1 root root   26 Mar 17 11:18 my.sh
-rw-r--r--. 1 root root  183 Mar 16 21:03 passwd
-rw-r--r--. 1 root root   54 Mar 17 10:21 test.txt
[root@openEuler ~]# ./for_test.sh
-bash: ./for_test.sh: Permission denied
[root@openEuler ~]# chmod a+x for_test.sh 
[root@openEuler ~]# ./for_test.sh 
root
[root@openEuler ~]# . for_test.sh 
root
[root@openEuler ~]# source for_test.sh 
root

Shell退出状态

        在Linux中执行命令后,会有一个状态,如果值为 0 表示之前执行的命令是正常执行的,如果是 非0 则表示前一条命令执行是有错误发生

示例:

[root@openEuler ~]# source for_test.sh 
root
[root@openEuler ~]# echo $?
0
[root@openEuler ~]# source for_test.sh1 
-bash: for_test.sh1: No such file or directory
[root@openEuler ~]# echo $?
1

变量和引用

什么是变量

        变量就是程序设计中一个可以变化的量,它会在内存中开辟一个空间,变量的名称引用是这个空间对应的地址,而这个地址中存储的就是变量的值

变量的命名

        在Shell中变量的名称可以由字母、数字和下划线组成,但是数字不能开头。原则上对变量的长度没有限制,但是一般不推荐变量名太长

变量的作用范围

        在Shell中命令的作用范围分为全局变量和局部变量全局变量也叫系统变量,它在整个系统都可以使用,而局部变量是需要在特定的环境中才可以使用

局部变量

        局部变量也叫做用户变量,或者临时变量,它只能在当前用户所在的环境中使用,或者在当前的会话中使用

示例:

[root@openEuler ~]# name=lisi
[root@openEuler ~]# echo $name
lisi
[root@openEuler ~]# echo ${name}
lisi# 产生一个子Shell环境
[root@openEuler ~]# bash
[root@openEuler ~]# echo $name# 退出到父Shell环境
[root@openEuler ~]# exit
exit
[root@openEuler ~]# echo ${name}
lisi

全局变量

        全局变量也叫做系统变量,也可以称为永久变量,它是不区分用户环境的,对整个系统都有效,它需要定义在 /etc/profile  或者  /etc/bashrc  文件中通过 export 来导出

示例:

        在 /etc/profile 中定义一个变量,编写这个文件,在这个文件的最后添加以下内容:

[root@openEuler ~]# vim /etc/profileexport MyPath=/root

        保存退出,然后测试是否能获取到定义的变量

[root@openEuler ~]# echo $MyPath[root@openEuler ~]# . /etc/profile[root@openEuler ~]# echo $MyPath
/root# 切换用户及环境后再测试
[root@openEuler ~]# su - redhat
[redhat@openEuler ~]$ echo $MyPath
/root[redhat@openEuler ~]$ exit
logout
[root@openEuler ~]# bash
[root@openEuler ~]# echo $MyPath
/root
[root@openEuler ~]# exit
exit

删除变量

        当我们不需要使用的时候,就可以把它删除,从而可以节省内存空间

        要删除变量就需要使用 unset 命令

语法:        

unset 变量名

示例:

        删除前面创建的变量

[root@openEuler ~]# echo $name
lisi
[root@openEuler ~]# unset name
[root@openEuler ~]# echo $name[root@openEuler ~]# 

变量的类型

        Shell是一种动态类型语言,也是一种弱类型的语言,所以在定义变量时,我们无需指定具体存放的值是什么类型(如:整数、小数、字符串等)

        在Shell,变量也存在类型,有以下几种

自定义变量
环境变量
只读变量
位置变量
预定义变量

自定义变量

        在Shell中,通常情况下都是用户在使用时直接定义的变量,而无需先进行定义

格式

        变量名=变量值

注意:

        1、等号两边不能有空格

        2、变量值如果是数字一般不加引导,如果是字符串推荐加引号;如果值包含有特殊字符或空格就必须要有引号

        3、引号可能是以下几种:

                1)单引号:被单引号包含的内容会原样输出

                2)双引号:被双引号包含的内容会把变量的值替换后再输出

                3)反引号:被反引号包含的命令执行的结果赋值给变量

查看变量的值

        在Shell中查看变量的值有以下几种:

                

echo $变量名
echo ${变量名}
set 查看系统中所有变量
env 查看系统环境变量
declare 查看输出的所有变量、函数等

示例:

[root@openEuler ~]# a=1
[root@openEuler ~]# echo $a
1
[root@openEuler ~]# echo ${a}
1
[root@openEuler ~]# ts=cs1
[root@openEuler ~]# echo $ts
cs1
[root@openEuler ~]# b = "hello"
-bash: b: command not found
[root@openEuler ~]# b ="hello"
-bash: b: command not found
[root@openEuler ~]# b= "hello"
-bash: hello: command not found
[root@openEuler ~]# b="hello"
[root@openEuler ~]# b='world'
[root@openEuler ~]# echo $b
world
[root@openEuler ~]# b=`pwd`
[root@openEuler ~]# echo $b
/root
[root@openEuler ~]# [root@openEuler ~]# env
SHELL=/bin/bash
HISTCONTROL=ignoredups
HISTSIZE=1000
HOSTNAME=openEuler
MyPath=/root
PWD=/root
LOGNAME=root
MOTD_SHOWN=pam
HOME=/root
LANG=en_US.UTF-8
对于单引号和双引号的区别
[root@openEuler ~]# age=18
[root@openEuler ~]# name=list
[root@openEuler ~]# echo "$name,$age"
list,18
[root@openEuler ~]# echo '$name,$age'
$name,$age
[root@openEuler ~]# echo "\$name"
$name
使用 declare 来定义变量

格式如下:

declare attribute variable

        attribute 可以是 +/- 来定义,如果是  -  表示为这个属性设置值,如果是 + 表示取消此属性

有以下属性:

-p表示所有变量的值
-i将变量定义为整数,如果不能转换为整数则为 0
-r将变量声明为只读变量
-a将变量声明为数组

使用示例:

# 使用 -i 属性来声明定义的变量 n 的类型是一个整数,如果n的值不能转换为整数,则以0填充
[root@openEuler ~]# declare -i n
[root@openEuler ~]# n=5
[root@openEuler ~]# n=a
[root@openEuler ~]# echo $n
0
[root@openEuler ~]# n=4
[root@openEuler ~]# echo $n
4# 使用 -r 属性来声明变量为只读的变量,对于只读变量来说,只能赋值一次,即它的值设置好后,就不能发生变量。
[root@openEuler ~]# declare -r name
[root@openEuler ~]# name=wangwu
-bash: name: readonly variable
[root@openEuler ~]# echo $name
list
[root@openEuler ~]# x=3
[root@openEuler ~]# declare -r x
[root@openEuler ~]# x=5
-bash: x: readonly variable# 使用 -a 属性来声明变量是一个数组,数组是通过下标来设置或获取数据的,下标是从0开始,最大的下标是数组的长度 - 1。如果希望获取数组中所有的元素(值),可以使用 `数组名[@]` 的形式来获取
[root@openEuler ~]# declare -a arr
[root@openEuler ~]# arr[0]="hello"
[root@openEuler ~]# arr[1]="world"
[root@openEuler ~]# arr[2]="shell"
[root@openEuler ~]# echo $arr[0]
hello[0]
[root@openEuler ~]# echo ${arr[0]}
hello
[root@openEuler ~]# echo ${arr[2]}
shell
[root@openEuler ~]# echo ${arr[5]}[root@openEuler ~]# echo ${arr[@]}
hello world shell
通过交互定义变量

        在编写Shell脚本时,我们会用到与用户进行交互,将用户输入的值赋予我们定义的变量,此时我们可以使用 read 命令来实现

格式:

read -p "输入提示信息" 变量名称

使用示例:

[root@openEuler ~]# read -p 'please input your number:' num
please input your number:18
[root@openEuler ~]# echo $num
18
[root@openEuler ~]# 

除了这种在命令行中使用外,还可以在脚本中使用

格式:

[root@openEuler ~]# vim my_read.sh
[root@openEuler ~]# cat my_read.sh#!/bin/bash
echo 'please input your number:'
read num
echo $num[root@openEuler ~]# ll
total 40
-rw-------. 1 root root  881 Mar 16 20:10 anaconda-ks.cfg
drwxr-xr-x. 2 root root 4096 Mar 17 10:29 d1
-rwxr-xr-x. 1 root root   24 Mar 23 14:32 for_test.sh
-rw-r--r--. 1 root root   49 Mar 16 21:07 hehe.txt
-rw-r--r--. 1 root root   35 Mar 17 09:51 message.txt
-rw-r--r--. 1 root root   69 Mar 23 16:12 my_read.sh
-rwxr-xr-x. 1 root root   26 Mar 17 11:18 my.sh
-rw-r--r--. 1 root root  183 Mar 16 21:03 passwd
-rw-r--r--. 1 root root   34 Mar 23 15:33 test.sh
-rw-r--r--. 1 root root   54 Mar 17 10:21 test.txt
[root@openEuler ~]# bash my_read.sh 
please input your number:
20
20

环境变量

        在Shell 中环境变量分为系统环境变量和用户环境变量,系统变量的定义参数前变量范围中的内容。而用户环境变量我们可以用户的家目录下的 ~/.bash_profile 文件或 ~/.bashrc 文件中定义的变量

        在Linux中内置了很多的环境变量,例如:

# 执行命令时搜索的路径,以冒号进行分隔
[root@openEuler ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/# 当前登录的用户名
[root@openEuler ~]# echo $USER
root# 当前登录用户的家目录
[root@openEuler ~]# echo $HOME
/root# 定义在命令模式下可以使用的命令行的长度
[root@openEuler ~]# echo $COLUMNS
156# 命令存放的历史文件
[root@openEuler ~]# echo $HISTFILE
/root/.bash_history

其实,以上的这些环境变量我们可以使用 env 命令来查看

示例:

[root@openEuler ~]# env
SHELL=/bin/bash
HISTCONTROL=ignoredups
HISTSIZE=1000
HOSTNAME=openEuler
MyPath=/root
PWD=/root
LOGNAME=root
MOTD_SHOWN=pam
HOME=/root
LANG=en_US.UTF-8
user1=root
SSH_CONNECTION=192.168.72.1 8175 192.168.72.150 22
SELINUX_ROLE_REQUESTED=
TERM=xterm
USER=root
SELINUX_USE_CURRENT_RANGE=
SHLVL=1
SSH_CLIENT=192.168.72.1 8175 22
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
SELINUX_LEVEL_REQUESTED=
MAIL=/var/spool/mail/root
SSH_TTY=/dev/pts/0
_=/usr/bin/env

只读变量

        如果希望定义的变量在程序的执行过程中不会发生变量,此时就可以声明为只读变量

        声明只读变量有两种方式

declare -r 变量名称
readonly 变量名称


使用示例:

[root@openEuler ~]# n=1
[root@openEuler ~]# n=2
[root@openEuler ~]# readonly n
[root@openEuler ~]# n=3
-bash: n: readonly variable

对于只读变量来说 ,不能使用 unset 来删除

位置变量

        Shell脚本执行时是需要接收用户输入的参数的,这时就需要使用到位置变量

特殊变量
特殊变量
$#表示参数的个数
$n其中n表示大于0的数字,表示第n个参数
$0表示这个被执行的脚本名称
$*表示获取所有的参数列表
$@表示获取所有的参数列表

使用示例:

# 编写一个脚本
[root@openEuler ~]# vim t1.sh
# 查看脚本内容
[root@openEuler ~]# cat t1.sh
#!/bin/bashecho "total parameters: $#"
echo "first parameter: $1"
echo "second parameter: $2"
echo "filename is: $0"
echo "all arguments: $*"
echo "all arguments: $@"# 运行脚本
[root@openEuler ~]# bash t1.sh python shell golang html
total parameters: 4
first parameter: python
second parameter: shell
filename is: t1.sh
all arguments: python shell golang html
all arguments: python shell golang html
$* 和 $@的区别
[root@openEuler ~]# set -- "hello" "world" "shell"
[root@openEuler ~]# echo $*
hello world shell
[root@openEuler ~]# echo $@
hello world shell
[root@openEuler ~]# for fname in "$@"; do echo $fname; done
hello
world
shell
[root@openEuler ~]# for fname in "$*"; do echo $fname; done
hello world shell

从上面的示例来说:

        $* 和 $@都可以获取到所有的参数列表,如果不加引号,它们没有区别,如果加了引号,区别如下:

        $@ 它是将参数以“参数1”“参数2”获取的,而 $*则是将参数以“参数1 参数2”的方式获取的

$?执行结果状态

        当脚本命令执行成功后,会有一个执行后的状态值,如果这个值为 0 则表示前一条命令执行成功,否则表示执行不成功,即有错误

[root@openEuler ~]# cat t2.sh
cat: t2.sh: No such file or directory
[root@openEuler ~]# echo $?
1
[root@openEuler ~]# cat t1.sh
#!/bin/bashecho "total parameters $#"
echo "first parameter $1"
echo "second parameter $2"
echo "filename is $0"
echo "all arguments $*"
echo "all arguments $@"
[root@openEuler ~]# echo $?
0
特殊状态变量

        在Shell特殊状态变量有以下几个:  

$$返回脚本进程的PID
$!获取上一个在后台的工作进程的PID
$_保存的是之前所执行命令的最后一个参数

以上三个是不常用的

[root@openEuler ~]# vim t2.sh
[root@openEuler ~]# cat t2.sh
#!/bin/bash[ $# -ne 2 ] && {echo "must be two arguments"exit 3
}
echo ok
echo "current shell pid: $$"		# 输出当前脚本执行时产生的 PID 值nohup ping www.baidu.com & 1>/dev/null		# 将 ping 命令的执行放到后台运行,并且不输出任何信息echo $!		# 输出上一个后台运行的命令的 PID 值

将脚本编写好后,通过如下方式来执行,从而得到如下结果

[root@openEuler ~]# bash t2.sh
must be two arguments[root@openEuler ~]# bash t2.sh a b
ok
current shell pid: 2540		# 脚本运行的PID
2541						# ping命令运行的PID
nohup: appending output to 'nohup.out'
[root@openEuler ~]# ps -ef | grep ping			# 查看ping 进程
root        2541       1  0 17:10 pts/0    00:00:00 ping www.baidu.com
root        2543    1666  0 17:10 pts/0    00:00:00 grep --color=auto ping
[root@openEuler ~]# echo $_		# 输出上一次命令的最后一个参数
b

变量的特殊用法

        在实际工作中,对变量的值还会有一些特殊用法,例如对变量的值的截取、替换、删除等

        要实现这些功能,则需要用到以下格式:

${变量}获取变量的值
${#变量}返回变量的长度,即字符串的长度
${变量:start}返回变量从 start 开始截取到变量最后,它是从0开始
${变量:start:length}截取变量的值中从start开始,到 length 长度的内容
${变量#word}将变量开头删除最短匹配的 word 子串

${变量##word}

将变量开头删除最长匹配的 word 子串
${变量%word}从变量结尾删除最短的 word
${变量%%word}从变量结尾删除最长的 word
${变量/parttern/string}使用 string 代替第一个匹配的 parttern
${变量//parttern/string}使用 string 代替所有匹配的 parttern

获取变量

${变量}获取变量的值
${#变量}返回变量的长度,即字符串的长度

使用示例:

[root@openEuler ~]# name="I am openEuler"
[root@openEuler ~]# echo ${name}
I am openEuler
[root@openEuler ~]# echo ${#name}
14

变量值截取

${变量:start}返回变量从 start 开始截取到变量最后,它是从0开始
${变量:start:length}截取变量的值中从 start 开始,到 length 长度的内容

使用示例:

[root@openEuler ~]# name="I am openEuler"
[root@openEuler ~]# echo ${name:2}
am openEuler
[root@openEuler ~]# echo ${name:2:5}
am op
[root@openEuler ~]# 

字符串删除

${变量#word}

将变量开头删除最短匹配的 word 子串

${变量##word}将变量开头删除最长匹配的 word 子串
${变量%word}从变量结尾删除最短的 word
${变量%%word}从变量结尾删除最长的 word

使用示例:

[root@openEuler ~]# name="abcABC123ABCabc"
[root@openEuler ~]# echo ${name}
abcABC123ABCabc
[root@openEuler ~]# echo ${name#a*c}		# 匹配最短,它是从前往后删除
ABC123ABCabc
[root@openEuler ~]# echo ${name##a*c}		# 匹配最长,它是从前往后删除[root@openEuler ~]# unset name
[root@openEuler ~]# name="abcABC123ABCabc"
[root@openEuler ~]# echo ${name}
abcABC123ABCabc
[root@openEuler ~]# echo ${name%a*c}		# 匹配最短,从后往前删除
abcABC123ABC
[root@openEuler ~]# echo ${name%%a*c}		# 匹配最长,从后往前删除[root@openEuler ~]# 

字符串替换

${变量/parttern/string}使用 string 代替第一个匹配的 parttern
${变量//parttern/string}使用 string 代替所有匹配的 parttern

使用示例:

[root@openEuler ~]# str="hello, I like your 10000 years"
[root@openEuler ~]# echo ${str}
hello, I like your 10000 years
[root@openEuler ~]# echo ${str/o/O}
hellO, I like your 10000 years
[root@openEuler ~]# echo ${str//o/O}
hellO, I like yOur 10000 years

删除文件名

准备测试数据

[root@openEuler ~]# mkdir sub_str
[root@openEuler ~]# cd sub_str/
[root@openEuler sub_str]# touch open_{1..5}_finish.jpg
[root@openEuler sub_str]# touch open_{1..5}_finish.png
[root@openEuler sub_str]# ll
total 0
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_1_finish.jpg
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_1_finish.png
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_2_finish.jpg
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_2_finish.png
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_3_finish.jpg
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_3_finish.png
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_4_finish.jpg
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_4_finish.png
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_5_finish.jpg
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_5_finish.png

需求:

        去掉所有文件中的_finish字符串

分析:

        1、可以通过 mv 命令来修改

                mv open_1_finish.jpg open_1.jpg

        2、获取文件

                f=open_1_finish.jpg

        3、通过字符串删除来实现

                ${f//_finish/}

实现:

# 查看当前目录下所有的文件
[root@openEuler sub_str]# ls
open_1_finish.jpg  open_2_finish.jpg  open_3_finish.jpg  open_4_finish.jpg  open_5_finish.jpg
open_1_finish.png  open_2_finish.png  open_3_finish.png  open_4_finish.png  open_5_finish.png# 循环这些文件并显示
[root@openEuler sub_str]# for f in `ls`
> do
> echo ${f}
> done
open_1_finish.jpg
open_1_finish.png
open_2_finish.jpg
open_2_finish.png
open_3_finish.jpg
open_3_finish.png
open_4_finish.jpg
open_4_finish.png
open_5_finish.jpg
open_5_finish.png# 通过循环来去掉 _finish 字符,但它并没有真正的修改磁盘中的文件,只是在内存中修改了
[root@openEuler sub_str]# for f in `ls`; do echo ${f//_finish/}; done
open_1.jpg
open_1.png
open_2.jpg
open_2.png
open_3.jpg
open_3.png
open_4.jpg
open_4.png
open_5.jpg
open_5.png
[root@openEuler sub_str]# ll
total 0
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_1_finish.jpg
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_1_finish.png
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_2_finish.jpg
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_2_finish.png
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_3_finish.jpg
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_3_finish.png
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_4_finish.jpg
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_4_finish.png
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_5_finish.jpg
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_5_finish.png# 结合 mv 命令来一个文件一个文件的修改  mv open_1_finish.jpg open_1.jpg
# open_1_finish.jpg 文件名称就是每次循环所得到的文件名 ${f}
# open_1.jpg 是通过 ${f//_finish/} 替换来到的
[root@openEuler sub_str]# for f in `ls`; do mv ${f} ${f//_finish/}; done
[root@openEuler sub_str]# for f in `ls`; do mv ${f} ${f##_finish}; done
[root@openEuler sub_str]# for f in `ls`; do mv ${f} ${f%%_finish}; done
[root@openEuler sub_str]# ll
total 0
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_1.jpg
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_1.png
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_2.jpg
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_2.png
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_3.jpg
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_3.png
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_4.jpg
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_4.png
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_5.jpg
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_5.png

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

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

相关文章

数据库原理(含思维导图)

数据库原理笔记&#xff0c;html与md笔记已上传 1.绪论 发展历程 记住数据怎么保存&#xff0c;谁保存数据&#xff0c;共享性如何&#xff0c;独立性如何 人工管理阶段 数据不保存应用程序管理数据数据不共享数据不具有独立性 文件系统阶段 数据可以长期保存文件系统管…

设计模式(6):桥接模式

一.桥接模式核心要点 处理多层继承结构&#xff0c;处理多维度变化的场景&#xff0c;将各个维度设计成独立的继承结构&#xff0c;使各个维度可以独立的扩展在抽象层建立关系。 \color{red}{处理多层继承结构&#xff0c;处理多维度变化的场景&#xff0c;将各个维度设计成独立…

最好的超声波清洗机排行榜有哪些?好评爆表超声波清洗机盘点

在如今这个视觉为王的时代&#xff0c;一副清晰的眼镜不仅是视力矫正的工具&#xff0c;更是提升形象的重要配饰。然而&#xff0c;眼镜的日常清洁往往让人头疼&#xff0c;传统的清洗方法既费时又难以彻底去除镜片上的污渍和细菌。这时&#xff0c;一台高效的超声波清洗机便成…

类与对象中C++

加油&#xff01;&#xff01;&#xff01; 文章目录 前言 一、类的6个默认成员函数 ​编辑 二、构造函数 1.概念 三、析构函数 1.概念 2.特性 四、拷贝构造函数 1.概念 2.特征 拷贝构造函数典型调用场景 五、赋值运算符重载 1.运算符重载 2.赋值运算符重载 赋值运算符重载格式…

module ‘numpy‘ has no attribute ‘int‘

在 NumPy 中&#xff0c;如果遇到了错误提示 "module numpy has no attribute int"&#xff0c;这通常意味着正在尝试以错误的方式使用 NumPy 的整数类型。从 NumPy 1.20 版本开始&#xff0c;numpy.int 已经不再是一个有效的属性&#xff0c;因为 NumPy 不再推荐使用…

软考 - 系统架构设计师 - 构件组装技术

概念 构件组装是将库中的构件经修改后相互连接&#xff0c;或者将它们和当前开发项目中的软件元素进行连接&#xff0c;最终构成新的目标构件。 构件组装技术是基于构件的软件开发的核心技术&#xff0c;也是构件技术研究的重点和难点。构件组装的目的是利用现有的构件组装成新…

西门子触摸屏SMART 700 IE V3数据记录的记录周期

问题的提出 需要解决的问题&#xff1a;目前我使用的工况是记录2s内速度变化情况&#xff0c;大概需要记录100个点&#xff0c;时间间隔或者说周期还是挺小的。 PLC端 S7-200的编程过程中&#xff0c;这个用填表程序add_to_table指令完成了&#xff0c;但是记录过程最多只能…

Chrome base 库详解:工具类和常用类库

Chrome浏览器使用了一个强大的库名为base&#xff0c;它包括了许多工具类和常用类库&#xff0c;以支持Chrome的底层功能和性能优化。在本文中&#xff0c;我们将详细阐述base库中的每个子项&#xff0c;并提供示例代码来展示其用法。 base 库的基本结构 Chrome的base库是一个…

ActiveMQ Artemis 系列| High Availability 主备模式(消息复制) 版本2.33.0

一、ActiveMQ Artemis 介绍 Apache ActiveMQ Artemis 是一个高性能的开源消息代理,它完全符合 Java Message Service (JMS) 2.0 规范,并支持多种通信协议,包括 AMQP、MQTT、STOMP 和 OpenWire 等。ActiveMQ Artemis 由 Apache Software Foundation 开发和维护,旨在提供可靠…

数字乡村发展之路:探索农村智慧化新模式

一、引言 随着信息技术的迅猛发展和普及&#xff0c;数字化已经成为推动乡村发展的重要引擎。数字乡村建设旨在通过信息化、智能化手段&#xff0c;提升农村地区的生产生活水平&#xff0c;推动农村经济社会的转型升级。本文旨在探讨数字乡村的发展之路&#xff0c;分析农村智…

BabyAGI源码解读(2)-核心agents部分

话不多说&#xff0c;我们直接进入babyAGI的核心部分&#xff0c;也就是task agent部分。 1. 创建任务agent 这一段代码的任务是创建一个任务&#xff0c;这个函数有四个参数 objective 目标result 结果&#xff0c;dict类型task_list 任务清单task_descritption 任务描述 …

【MySql】利用DataX同步mysql数据,多数据源数据同步方案

你说你知道他们的世界 悲歌三首买一切 买昆仑落脚 蓬莱放思想 买人们的争执酿酒汤 买公主坟的乌鸦 事发之木和东窗之麻 买胭脂河里船行渔歌 黄金世界中万物法则 你我都一样 将被遗忘 郭源潮 你的病也和我的一样 风月难扯 离合不骚 层楼终究误少年 自由早晚乱余生 你我山前没相见…

iOS开发进阶之列表加载图片

iOS开发进阶之列表加载图片 列表加载图片通常使用UITableView或UICollectionView&#xff0c;由于列表中内容数量不确定并且对于图片质量要求也不确定&#xff0c;所以对于图片加载的优化是很有必要的。 首先借鉴前文&#xff0c;我们逐步进行操作&#xff0c;以下是加载1000…

基于springboot实现数据库的加解密

项目地址 https://github.com/Chenchicheng/spring-ibatis-encryption 功能说明 支持使用注解的方式目标类进行加解密支持同一个类多个字段分别使用不同的加密方式支持自定义加密方法 本地调试 pull代码到本地&#xff0c;更换application.yml中的数据库用户名和密码&…

nginx用法以及核心知识详解-可以当作使用nginx的操作手册

前言 nginx的使用真的是非常简单&#xff0c;下载下来解压运行就可以&#xff0c;配置都是再conf文件夹的里的nginx.conf文件里配置&#xff0c;所以对于nginx的上手使用&#xff0c;nginx.conf文件里字段的含义是需要掌握的&#xff0c;然后就是一些nginx的常见问题 nginx核心…

.NET CORE 分布式事务(三) DTM实现Saga及高并发下的解决方案

目录(结尾附加项目代码资源地址) 引言&#xff1a; 1. SAGA事务模式 2. 拆分为子事务 3. 失败回滚 4. 如何做补偿 4.1 失败的分支是否需要补偿 5. 异常 6. 异常与子事务屏障 6.1 NPC的挑战 6.2 现有方案的问题 6.3 子事务屏障 6.4 原理 7. 更多高级场景 7.1 部分…

永磁同步电机初始转子位置检测

/// https://zhuanlan.zhihu.com/p/409887456 ///

vue3+threejs新手从零开发卡牌游戏(二十二):添加己方游戏流程(先后手、抽牌、主要阶段、战斗阶段、结束阶段)

首先在utils/common.ts里定义一些流程相关的变量&#xff1a; const flow ref([ // 游戏流程{name: "抽卡阶段"},{name: "主要阶段"},{name: "战斗阶段"},{name: "结束阶段"}])const flowIndex ref(0) // 当前流程const currentPla…

[C++初阶] 爱上C++ : 与C++的第一次约会

&#x1f525;个人主页&#xff1a;guoguoqiang &#x1f525;专栏&#xff1a;我与C的爱恋 本篇内容带大家浅浅的了解一下C中的命名空间。 在c中&#xff0c;名称&#xff08;name&#xff09;可以是符号常量、变量、函数、结构、枚举、类和对象等等。工程越大&#xff0c;名称…

什么是gif? 如何把视频格式转成gif动图格式?展现动图的魅力

一&#xff0c;什么是gif格式 gif是一种位图图形文件格式&#xff0c;主要用于显示索引彩色图像。gif格式在1987年由CompuServe公司开发&#xff0c;它采用LZW&#xff08;Lempel-Ziv-Welch&#xff09;无损压缩算法&#xff0c;这种算法可以有效地减少图像文件在网络上传…