【Linux基础】Shell脚本

news/2025/2/24 14:55:23

文章目录

  • 一、前言
  • 二、Linux脚本编写基础
    • 2.1 文件开头
    • 2.2 注释
    • 2.3 变量
      • 2.3.1 系统变量
      • 2.3.2 环境变量
      • 2.3.3 用户环境变量
    • 2.4 注意事项
  • 三、shell脚本中常用的三类命令
    • 3.1 Linux命令
    • 3.2 管道、重定向和命令置换
      • 3.2.1 管道
      • 3.2.2 重定向
      • 3.2.3 命令置换
  • 四、流程控制
    • 4.1 说明性语句
    • 4.2 功能性语句
    • 4.3 结构性语句
      • 4.3.1 条件语句
        • 4.3.1.1 if语句
        • **4.3.1.2 ****case多路分支语句**
        • 4.3.1.3 for循环语句
        • 4.3.1.4 while循环语句
        • 4.3.1.5 select选择语句
  • 五、函数
    • 5.1 函数语法
    • 5.2 函数变量作用域
    • 5.3 函数的传参
    • 5.4 函数的返回值
      • 5.4.1 使用echo或者其他命令输出
      • 5.4.2 第二种方式
  • 六、数组
  • 七、其他
    • :命令
    • eval命令
    • exit命令
    • export命令
    • set命令
    • unset命令
  • 八、正则表达式

一、前言

本文章主要写的是shell脚本的相关内容,用于自用和新手入门。

二、Linux脚本编写基础

2.1 文件开头

不支持 Bash 特有的扩展功能(如数组、算数运算等)。

#!/bin/sh  

需要在脚本中使用 Bash 特有的功能或扩展

#!/bin/bash

2.2 注释

使用#开头

#这是注释

2.3 变量

无需定义,输出需要使用$(xx)来防止错误。任何数据都解释成一串字符。

变量=value

count=1
echo $count
DATE=$(date)
echo $DATE

有三种变量:用户自定义变量、系统变量、环境变量

用户自定义变量通常用大写变量来区别,COUNT=1

unset命令删除变量的赋值。

2.3.1 系统变量

用法:主要是用于对参数判断和命令返回值判断时使用。

 $0   与键入的命令行一样,包含脚本文件名
 $1,$2,……$9  分别包含第一个到第九个命令行参数
 $*   包含所有命令行参数
 $#   包含命令行参数的个数
 $?   前一个命令的退出状态,返回0表示执行成功
 $$   包含正在执行进程的ID号

2.3.2 环境变量

用法:主要是在程序运行时需要设置。

PATH    		shell搜索路径,以冒号(:)分割。
HOME    		/etc/passwd文件中列出的用户主目录。
SHELL   		显示当前的shell类型。
USER    		打印当前用户名。
ID      		打印当前用户id信息。
PWD    			显示当前所在路径。
TERM    		打印当前终端类型。常用的有vt100,ansi,vt200,xterm等
HOSTNAME    显示当前主机名。
PS1,PS2:		默认提示符($)及换行提示符(>)
HISTSIZE    历史命令大小,可通过HISTTIMEFORMAT变量设置命令执行时间。
PANDOM    	随机生成一个0到32767的整数。
IFS:Internal Field Separator, 默认为空格,tab及换行符。
$PATH:取PATH变量里面的值。

2.3.3 用户环境变量

用法:又称局部变量,主要是用在shell脚本内部或者临时局部使用。

2.4 注意事项

1.shell命名:一般为英文、大写、小写、后缀为.sh结尾。不能用特殊符号、空格。

2.shell脚本变量:不能以数字、特殊符号开头,可以使用下划线不能用破折号

3.";"在bash脚本中是命令分隔符,用于在同一行中分隔多个命令。

4.||:or操作符。当||左边的命令执行失败(返回非零值)时,||右边的命令才会被执行。

5.&& || 这两个符号组合起来可以实现类似三目运算符的功能。

6.单引号:

不会进行变量或命令的替换:在单引号内的所有内容都会被当作普通字符处理,即使其中包含变量或命令,Shell也不会尝试去替换它们。

不支持转义字符:在单引号内的字符都是字面意义上的字符,包括反斜杠 ()。

7.双引号:

会进行变量或命令的替换:在双引号内的变量或命令会被Shell替换为相应的值或输出。

支持部分转义字符:双引号内支持一些转义字符,例如 \n 代表换行,\t 代表制表符等。但是,有些转义字符(如 KaTeX parse error: Undefined control sequence: \) at position 6: 、` 和 \̲)̲在双引号中有特殊的意义。在双引…()的方式执行命令等操作。

三、shell脚本中常用的三类命令

3.1 Linux命令

看我之前的Linux下常用的系统命令

3.2 管道、重定向和命令置换

3.2.1 管道

将一个命令的输出作为另外一个命令的输入。

grep "hello" file.txt | wc -l 
在file.txt中搜索包含有”hello”的行并计算其行数。 
在这里grep命令的输出作为wc命令的输入。wc -l用来统计行数

3.2.2 重定向

将命令的结果输出到文件,而不是标准输出(屏幕)。

是写入文件并覆盖旧文件。

加到文件的尾部,保留旧文件内容。

<输入重定向,将文件内容作为输入传递给命令。

ls -l > lsoutput.txt
通过>操作符把标准输出重定向到一个文件。默认情况下,如果该文件已经存在,其内容将被覆盖。
    
ps >> lsoutput.txt
>>操作符将输出内容附加到一个文件中。

more < killout.txt  
<代表重定向输入   more命令与cat类似,只不过可以一页一页输出

需要注意的是,如果有一系列的命令需要执行,相应的输出文件是在这一组命令被创建的同时立刻被创建或写入的,所以不要在命令流中重复使用相同的文件名。

3.2.3 命令置换

方法一:

command1 command2

echo `wc -l < /etc/passwd`

方法二:

command1 $(command2)

echo $(wc -l < /etc/passwd)

四、流程控制

在 Shell 脚本中,通常将语句分为说明性语句、功能性语句和结构性语句这三类。

4.1 说明性语句

#! /bin/sh

4.2 功能性语句

read:从标准输入读入一行,并赋值给后面的变量。

read var
read username
read year month day

4.3 结构性语句

4.3.1 条件语句

4.3.1.1 if语句

配合test或者[]使用。使用[]时,必须要在[符号和被检查的条件之间留出空格,可以把[符号看作和test一样,test和后面的条件之间总是有一个空格。如果要把then放在和if同一行上,则必须要用一个分号把if和then分开。

格式

if(表达式)
then
  语句1
elif(表达式)
then
  语句2
else
  语句3
fi
#!/bin/sh

#从键盘输入一个代表天气的字符串,如果是晴天,就出去玩

read str
if test ${str} = "晴天";then
    echo "出去玩"
fi
#!/bin/sh

#从键盘输入一个代表天气的字符串,如果是晴天,就出去玩

read str
if [ ${str} = "晴天" ];then
    echo "出去玩"
fi
字符串测试结果
s1 = s2测试两个字符串的内容是否完全一样
s1 != s2测试两个字符串的内容是否有差异
-z s1测试s1 字符串的长度是否为0
-n s1测试s1 字符串的长度是否不为0
整数测试
a -eq b测试a与b是否相等
a -ne b测试a与b是否不相等
a -gt b测试a是否大于b
a -ge b测试a是否大于等于b
a -lt b测试a 是否小于b
a -le b测试a是否小于等于b
文件测试
-d name 测试name 是否为一个目录,判断目录是否存在。
-e name测试一个文件是否存在。
-f name测试name 是否为普通文件,判断文件是否存在。
-L name测试name 是否为符号链接。
-r name测试name 文件是否存在且为可读。
-w name测试name 文件是否存在且为可写。
-x name测试name 文件是否存在且为可执行。
-s name 测试name 文件是否存在且其长度不为0。
f1 -nt f2测试文件f1 是否比文件f2 更新。
f1 -ot f2 测试文件f1 是否比文件f2 更旧。
**4.3.1.2 **case多路分支语句

主要用于对多个选择条件进行匹配输出,与if elif语句结构类似,通常用于脚本传递输入参数,打印出输出结果及内容。

格式

case 字符串变量(模式名) in
模式1)
  命令表1
  ;;
模式2)
  命令表2
  ;;
模式n)
  命令表n
  ;;
*)
  不符合以上模式执行的命令
esac

注:

  1. case语句只能检测字符串变量
  2. 各模式中可用文件名元字符,以右括号结束
  3. 一次可以匹配多个模式用“|”分开
  4. 命令表以单独的双分号行结束,退出case语句
  5. 模式 n常写为字符* 表示所有其它模式
  6. 最后一个双分号行可以省略
 #!/bin/sh
echo “Is it morning?Please answer yes or no”
read timeofday
case$timeofdayin
  yes|y) echo "Good Morning";;
  no|n) echo "Good Afternoon";;
  *) echo "answer not recognized";;
esac
exit 0
4.3.1.3 for循环语句

格式

#格式:for name [ [ in [ word ... ] ] ; ] do list ; done

for 变量名 in 取值列表
do
  语句 1
done

例:
for a in 1 2 3 4 5
do
    echo $a
done

( s e q 1254 ) :这是一个 < / f o n t > 命令替换 < f o n t s t y l e = " c o l o r : r g b ( 51 , 51 , 51 ) ; " > 的结构。 (seq 1 254):这是一个</font>命令替换<font style="color:rgb(51, 51, 51);">的结构。 (seq1254):这是一个</font>命令替换<fontstyle="color:rgb(51,51,51);">的结构。(…) 表示执行其中的命令,并将其标准输出替换到当前位置。

seq 1 254 是一个 Unix 命令,用于生成从 1 到 254 的整数序列。

&&和||是条件操作符。如果ping命令成功执行(即主机在线),则result被设置为0;否则,result被设置为1。

#!/bin/bash
#check hosts is on/Off 
#功能:检查多台主机存活情况。
Network=$1

for Host in $(seq 1 254)
do
ping -c 1 $Network.$Host > /dev/null && result=0 || result=1
if [ "$result" == 0 ];then
  echo -e "\033[32;1m$Network.$Host is up \033[0m"
  echo "$Network.$Host" >> /tmp/up.txt
else
  echo -e "\033[;31m$Network.$Host is down \033[0m"
  echo "$Network.$Host" >> /tmp/down.txt
fi
done
4.3.1.4 while循环语句

格式

while  (表达式)
do
  语句1
done

例1:

let是一个Bash内置命令,用于执行算术操作。这里N++将变量N的值增加1。如果N之前没有定义或赋值,那么它会被初始化为0,并且其值在每次循环时递增1。

while true
do
  let N++
  if [ $N -eq 5 ]
  then
    break
  fi
  echo $N
done

例2:

i=0
while ((i<=100))
do
  echo  $i
  i=`expr $i + 1`
done

在Bash脚本中,while ((i<=100)) 和 while [ i<=100 ] 的条件判断方式存在显著区别:

  • while ((i<=100)) 使用了Bash的算术扩展语法,允许直接在条件中进行算术运算和比较。这种写法下,i会被解释为变量名,并与100进行数值比较,无需额外的引号或转义处理。
  • while [ i<=100 ] 则使用了基本的括号测试结构。在这一结构中,i<=100会被当作字符串整体处理,而不是进行数值比较,这会导致测试失败,无法实现预期的循环控制功能。
    建议在需要进行数值比较时使用((…))结构,以确保条件判断的准确性。
 while [ $i -le 100 ]
do
echo $i  
i=$((i + 1))  
done

i=expr i + 1 等价于 i = i + 1等价于i= i+1等价于i=((i + 1)):expr的作用是告诉程序后面是进行算数运算。

j=expr $i + j 等价于 j = j等价于j= j等价于j=((i+j))。

例3:

[root@web-server01~/script]# vim login.sh 
#!/bin/bash
#Check File to change. 
#By author rivers 2021-9-27
USERS="hbs"
while true
do
  echo "The Time is `date +%F-%T`"
  sleep 10
  NUM=`who|grep "$USERS"|wc -l`
  if [[ $NUM -ge 1 ]];then
    echo "The $USERS is login in system."
  fi
done

date +%F-%T --> 2024-04-21-15:42:04
4.3.1.5 select选择语句

格式:

#select 是一个类似于 for 循环的语句
#Select语句一般用于选择,常用于选择菜单的创建,可以配合PS3来做打印菜单的输出信息,其语法格式以select…in do开头,done结尾:
#先设置ps3的值,我们输入的数据会保存到i中,表达式会显示选项
PS3=""
select i in (表达式) 
do
语句
done

例1:

选择mysql版本

#!/bin/bash
#by author rivers on 2021-9-27
PS3="Select a number: "
while true
do
  select mysql_version in 5.1 5.6 quit
  do
    case $mysql_version in
    5.1)
      echo "mysql 5.1"
      break
      ;;
    5.6)
      echo "mysql 5.6"
      break
      ;;
    quit)
      exit
      ;;
    *)
      echo "Input error, Please enter again!"
      break
    esac
  done
done

五、函数

Shell编程函数默认不能将参数传入()内部,Shell函数参数传递在调用函数名称传递,例如name args1 args2。

5.1 函数语法

定义一个函数,只需简单的写出它的名字,然后是一对空括号,再把有关的语句放在一对花括号中

#!/bin/sh
foo()
{
echo “this is a example”
}
echo “script starting”
foo #直接调用
echo “script ended”
exit 0

5.2 函数变量作用域

如果要在shell函数中声明局部变量,则要使用local关键字,局部变量的作用域则局限在函数范围

内。此外,函数还可访问全局作用范围内的其他shell变量。如果全局变量和局部变量出现了同

名,则局部变量会覆盖全局变量,但仅限于函数范围内。

声明局部变量的格式:Local variable_name =value

例一:

#!/bin/sh
sample_text="global variable"
foo()
{
local sample_text="local variable"
echo "function is executing"
echo $sample_text
}
echo "script starting"
foo
echo $sample_text
echo "script ending"
exit 0

5.3 函数的传参

当一个函数被调用时,脚本程序的位置参数$*, $@, $#, $1, $2等会被替换为函数的参数,当函数执行完毕后,这些参数会恢复为他们先前的值。

#!/bin/sh
foo()
{
echo $0
echo $1
echo aa
}
foo aa bb cc
echo $0 $1
#运行如下
#./test ee rr
./test
aa
aa
./test ee

5.4 函数的返回值

5.4.1 使用echo或者其他命令输出

  • 在 Shell 脚本中,函数的返回值并不是通过 return 语句来传递的,而是通过函数的标准输出(stdout)。当你在函数中使用 echo 或其他命令输出内容时,这些内容会被捕获并赋值给变量。
  • result=$(foo) 使用了命令替换(Command Substitution)语法 $(…)。它的作用是执行括号中的命令,并将命令的输出作为变量的值。如果函数 foo 中有多个 echo 语句,命令替换 $(foo) 会捕获函数中所有 echo 的输出,并将它们作为一个整体赋值给变量 result。换言之,所有输出会按顺序拼接在一起,并存储到变量中。
#!/bin/sh
foo()
{
  echo "JAY"
}
result=$(foo)
echo "aaa".$result."bb"
#运行如下
#./aa
aaa.JAY.bb

备注:

$* 和 $@ 都表示传递给函数或脚本的所有参数,当 $* 和 $@ 不被双引号包围时,它们之间没有任何区别,都是将接收到的每个参数看做一份数据,彼此之间以空格来分隔。

但当他们加上双引号后就有区别了:

“$*” 会将所有的参数从整体上看做一份数据,而不是把每个参数都看做一份数据。

“$@” 仍然将每个参数都看作一份数据,彼此之间是独立的。

5.4.2 第二种方式

格式

function_name [arg1 arg2 … ]
echo $?

获取函数的返回的状态

在 Shell 脚本中,return 命令用于从函数中返回一个退出状态码(exit status),但它并不限于只能返回 0 或 1。实际上,return 可以返回 0 到 255 之间的任何整数值。

check_user( )    
{  
  #查找已登录的指定用户
  user=`who  |  grep  $1 | wc -l`
  if [ $user –eq 0 ]
  then
    return  0       #未找到指定用户
  else
    return  1       #找到指定用户
  fi
}

while  true         # MAIN, Main, main:   program  begin  here
do
  echo  "Input username: \c"
  read   uname
  check_user  $uname       # 调用函数, 并传递参数uname
  if [ $? –eq  1 ]         # $?为函数返回值
  then
    echo  "user  $uname  online"
  else
    echo  "user  $uname  offline"
  fi
done

六、数组

格式

array=(元素1 元素2 元素3 ...)

用小括号初始化数组,元素之间用空格分隔。

定义方法 1:初始化数组 array=(a b c)

定义方法 2:新建数组并添加元素 array[下标]=元素

定义方法 3:将命令输出作为数组元素array=($(command))

#方法 1:
#!/bin/bash
IP=(10.0.0.1 10.0.0.2 10.0.0.3)
for ((i=0;i<${#IP[*]};i++))
do
  echo ${IP[$i]}
done

eg:
10.0.0.1
10.0.0.2
10.0.0.3
#方法 2:
#!/bin/bash
IP=(10.0.0.1 10.0.0.2 10.0.0.3)
for IP in ${IP[*]}
do
  echo $IP
done 

${IP[*]} 用于表示数组 IP 的所有元素。具体地说,它会将数组 IP 中的所有元素作为独立的字符串参数展开。

I P [ @ ] 、 {IP[@]}、 IP[@]{IP[*]}的区别

在 Bash shell 脚本中,${IP[@]} 和 ${IP[*]} 都用于访问数组 IP 的所有元素,但是它们在处理数组元素时的行为略有不同,特别是在涉及引号、空格和通配符时。

1.引号处理:

${IP[@]} 会保留数组元素中的引号,这意味着如果数组元素包含空格或特殊字符,并且这些字符被引号括起来,那么 ${IP[@]} 将确保这些引号在展开时仍然存在。

${IP[*]} 则不会保留引号,它简单地将所有元素连接成一个由空格分隔的字符串。如果数组元素中有空格或特殊字符,并且它们没有被引号括起来,那么这些元素可能会被错误地解释。

2.通配符扩展:

${IP[@]} 在展开时不会执行通配符扩展(即文件名扩展)。如果数组元素包含通配符(如 *),那么这些通配符将保持原样,不会被扩展为匹配的文件名。

${IP[]} 在某些情况下会执行通配符扩展。如果数组元素包含通配符,并且这些通配符在当前上下文中可以匹配到文件名,那么 ${IP[]} 会将这些通配符扩展为匹配的文件名列表。

3.安全性:

由于 ${IP[@]} 保留了引号并且不会执行通配符扩展,它通常更安全,特别是在处理包含空格、特殊字符或通配符的数组元素时。

${IP[*]} 可能会在处理这些元素时引入意外的行为,因此在使用时需要更加小心。

七、其他

:命令

冒号(:)是一个空命令,它偶尔会被用于逻辑简化,相当于true的一个别名,由于它是内置命

令,所以它的运行效率要比true高。

eval命令

eval命令允许对参数进行求值。它是shell的内置命令,通常不会以单独命令的形式存在。

foo=10
x=foo
y='$'$x 相当于y=$foo
echo $y
打印出的结果是$foofoo=10
x=foo
eval y='$'$x
echo $y
输出是10
当然你也可以用另外一种方法对变量求值
y=$(($x)) //相当于求值再求值

exit命令

exit n命令以退出码n结束运行。

如果你在退出时没有指定一个退出状态,那么最后一条被执行的命令的状态将被用作返回值。

在shell脚本编程中,0表示成功,1-125是脚本程序使用的错误代码

export命令

export命令将作为它参数的变量导出到子shell中,并使之在子shell中有效。

export2:

#!/bin/sh
echo "$foo"
echo "$bar"
export1:

#!/bin/sh
foo="the first meta-syntactic variable"
export bar="the second meta-syntactic variable"
./export2

运行export1,输入如下:


the second meta-syntactic variable

第一个空行的出现是因为变量foo在export2中不可用,所以$foo被赋值为空,echo一个空变

量将输出一个空行。

注意:当变量被一个shell导出后,它就可以被该shell调用的任何脚本使用,也可以被后续

调用的任何shell使用。如果export2调用了另一个脚本,bar的值对新脚本来说仍然有效。

set命令

set命令的作用是为shell设置参数变量(实际上就是给$0、$1等赋值)。

#!/bin/sh
echo the date is $(date)
set $(date)
echo the month is $2

#输出如下
the date is 2019年 09月 12日 星期四 15:06:23 CST
the month is 09月

unset命令

unset命令的作用是从环境变量中删除变量或函数。这个命令不能删除shell本身定义的只读变

量。

#!/bin/sh
foo="hello world"
echo $foo
unset foo
echo $foo
#输出如下,第二行为空
hello world

八、正则表达式

使用shell时,从一个文件中抽取多于一个字符串将会很麻烦。例如,在一个文本中抽取一个词,它的头

两个字符是大写的,后面紧跟四个数字。如果不使用某种正则表达式,在shell中将很难实现这个操作。

^锚定行的开始,如:'^grep’匹配所有以grep开头的行。
$锚定行的结束,如:'grep$'匹配所有以grep结尾的行。
.匹配一个非换行符的字符,如:'gr.p’匹配gr后接一个任意字符,然后是p。
*匹配零个或多个先前字符,如:*grep 匹配所有一个或多个字符后紧跟grep的行。. 一起用代表任意字符。
[]匹配一个指定范围内的字符,如’[Gg]rep’匹配Grep和grep。
[^]匹配一个不在指定范围内的字符,如:'[^ A-FH-Z]rep’匹配不包含A-F和H-Z的一个字母开头,紧跟rep的行。
<锚定单词的开始,如:'<grep’匹配包含以grep开头的单词的行。
>锚定单词的结束,如’grep>'匹配包含以grep结尾的单词的行。
x{m}含有重复字符x,m次的字符串,如:‘0{5}’匹配包含5个0的行。实际上是 重复字符x,m至少m次
x{m,}重复字符x,至少m次
x{m,n}重复字符x,至少m次,不多于n次,如:‘o{5,10}’匹配5–10个o的行。(多于N次好像也OK)
\w匹配字母和数字字符,也就是[A-Za-z0-9],如:'G\w*p’匹配以G后跟零个或多个文字或数字字符,然后是p。
\W\w的反置形式,匹配一个或多个非单词字符,如点号句号等。

使用grep命令

#!/bin/sh

text="Hello, World!"
pattern="^Hello.*World!$"

if echo "$text" | grep -qP "$pattern"; then
    echo "Match found!"
else
    echo "No match."
fi

#输出
Match found!

使用sed命令

#!/bin/sh

text="Hello, World!"
pattern="Hello"

# 替换 "Hello" 为 "Hi"
result=$(echo "$text" | sed "s/$pattern/Hi/")
echo "$result"

#输出
Hi, World!

使用awk命令

#!/bin/sh

text="Hello, World!"
pattern="Hello"

# 检查是否包含 "Hello"
if echo "$text" | awk "/$pattern/ {print 'Match found!'}"; then
    echo "Match found!"
else
    echo "No match."
fi
#输出
Match found!

http://www.niftyadmin.cn/n/5864490.html

相关文章

软件需求类的论文无法量化评价的问题

软件需求研究的量化难题确实是一个普遍存在的挑战&#xff0c;主要原因在于需求工程本身具有强主观性、领域依赖性和过程复杂性。针对这一问题&#xff0c;可以从以下角度进行突破性思考并提出解决方案&#xff1a; 1. 构建多维度评估体系&#xff08;Multi-dimensional Evalu…

《Linux命令行和shell脚本编程大全》第一章阅读笔记

一.认识Linux Linux系统可以划分为四个部分 Linux内核GNU工具图形化桌面环境应用软件 1.Linux内核 主要功能有 系统内存管理软件程序管理硬件设备管理文件系统管理 &#xff08;1&#xff09;系统内存管理 内核管理可用物理内存&#xff0c;还可以创建并管理虚拟内存。内…

本地部署AI模型 --- DeepSeek(二)---更新中

目录 FAQ 1.Failed to load the model Exit code: 18446744072635812000 FAQ 1.Failed to load the model Exit code: 18446744072635812000 问题描述&#xff1a; &#x1f972; Failed to load the model Error loading model. (Exit code: 18446744072635812000). Unkn…

react路由总结

目录 一、脚手架基础语法(16~17) 1.1、hello react 1.2、组件样式隔离(样式模块化) 1.3、react插件 二、React Router v5 2.1、react-router-dom相关API 2.1.1、内置组件 2.1.1.1、BrowserRouter 2.1.1.2、HashRouter 2.1.1.3、Route 2.1.1.4、Redirect 2.1.1.5、L…

详解 @符号在 PyTorch 中的矩阵乘法规则

详解 符号在 PyTorch 中的矩阵乘法规则 在 PyTorch 和 NumPy 中&#xff0c; 符号被用作矩阵乘法运算符&#xff0c;它本质上等价于 torch.matmul() 或 numpy.matmul()&#xff0c;用于执行张量之间的矩阵乘法。 在本篇博客中&#xff0c;我们将深入探讨&#xff1a; 运算符…

Kafka系列之:记录一次源头数据库刷数据,造成数据丢失的原因

Kafka系列之:记录一次源头数据库刷数据,造成数据丢失的原因 一、背景二、查看topic日志信息三、结论四、解决方法一、背景 源头数据库在很短的时间内刷了大量的数据,部分数据在hdfs丢失了 理论上debezium数据采集不会丢失,就需要排查数据链路某个节点是否有数据丢失。 数据…

Unity Android SDK 升级、安装 build-tools、platform-tools

Unity Android SDK 升级、安装 build-tools、platform-tools 通过 Unity Hub 安装的 Android SDK 需要下载 特定版本的 build-tools、platform-tools 如何操作&#xff1f; 以 Unity 2022.3.26f1 为例&#xff0c;打开安装目录&#xff0c;找到如下目录 2022.3.26f1\Editor\…

0083.基于springboot+uni-app的社区车位租赁系统小程序+论文

一、系统说明 基于springbootuni-app的社区车位租赁系统小程序,系统功能齐全, 代码简洁易懂&#xff0c;适合小白学编程。 现如今&#xff0c;信息种类变得越来越多&#xff0c;信息的容量也变得越来越大&#xff0c;这就是信息时代的标志。近些年&#xff0c;计算机科学发展…