Bash 脚本教程
注:本文为 “Bash 脚本编写” 相关文章合辑。
BASH 脚本编写教程
as good as well于 2017-08-04 22:04:28 发布
这里有个老 American 写的 BASH 脚本编写教程,非常不错,至少没接触过 BASH 的也能看懂!
建立一个脚本
Linux 中有好多中不同的 shell,但是通常我们使用 bash (bourne again shell) 进行 shell 编程,因为 bash 是免费的并且很容易使用。所以在本文中笔者所提供的脚本都是使用 bash(但是在大多数情况下,这些脚本同样可以在 bash 的大姐,bourne shell 中运行)。
如同其他语言一样,通过我们使用任意一种文字编辑器,比如 nedit、kedit、emacs、vi 等来编写我们的 shell 程序。
程序必须以下面的行开始(必须放在文件的第一行):
#!/bin/sh
符号 #!
用来告诉系统它后面的参数是用来执行该文件的程序。在这个例子中我们使用 /bin/sh
来执行程序。
当编辑好脚本时,如果要执行该脚本,还必须使其可执行。
要使脚本可执行:
chmod +x filename
然后,您可以通过输入:./filename
来执行您的脚本。
注释
在进行 shell 编程时,以 #
开头的句子表示注释,直到这一行的结束。我们真诚地建议您在程序中使用注释。如果您使用了注释,那么即使相当长的时间内没有使用该脚本,您也能在很短的时间内明白该脚本的作用及工作原理。
变量
在其他编程语言中您必须使用变量。在 shell 编程中,所有的变量都由字符串组成,并且您不需要对变量进行声明。要赋值给一个变量,您可以这样写:
变量名=值
取出变量值可以加一个美元符号($
)在变量前面:
#!/bin/sh#对变量赋值:
a="hello world"# 现在打印变量a的内容:
echo "A is:"
echo $a
在您的编辑器中输入以上内容,然后将其保存为一个文件first
。之后执行chmod +x first
使其可执行,最后输入./first
执行该脚本。
这个脚本将会输出:
A is:
hello world
有时候变量名很容易与其他文字混淆,比如:
num=2
echo "this is the $numnd"
这并不会打印出"this is the 2nd",而仅仅打印"this is the ",因为shell会去搜索变量numnd
的值,但是这个变量是没有值的。可以使用花括号来告诉shell我们要打印的是num
变量:
num=2
echo "this is the ${num}nd"
这将打印: this is the 2nd
有许多变量是系统自动设定的,这将在后面使用这些变量时进行讨论。
如果您需要处理数学表达式,那么您需要使用诸如expr
等程序(见下面)。
除了一般的仅在程序内有效的shell变量以外,还有环境变量。由export
关键字处理过的变量叫做环境变量。我们不对环境变量进行讨论,因为通常情况下仅仅在登录脚本中使用环境变量。
Shell 命令和流程控制
在 shell 脚本中可以使用三类命令:
1) Unix 命令:
虽然在 shell 脚本中可以使用任意的 unix 命令,但是还是由一些相对更常用的命令。这些命令通常是用来进行文件和文字操作的。
常用命令语法及功能
echo "some text"
: 将文字内容打印在屏幕上ls
: 文件列表wc –l file
wc -w file
wc -c file
: 计算文件行数计算文件中的单词数计算文件中的字符数cp sourcefile destfile
: 文件拷贝mv oldname newname
: 重命名文件或移动文件rm file
: 删除文件grep 'pattern' file
: 在文件内搜索字符串比如:grep 'searchstring' file.txt
cut -b colnum file
: 指定欲显示的文件内容范围,并将它们输出到标准输出设备比如:输出每行第5个到第9个字符cut -b5-9 file.txt
千万不要和cat
命令混淆,这是两个完全不同的命令cat file.txt
: 输出文件内容到标准输出设备(屏幕)上file somefile
: 得到文件类型read var
: 提示用户输入,并将输入赋值给变量sort file.txt
: 对file.txt
文件中的行进行排序uniq
: 删除文本文件中出现的行列比如:sort file.txt \| uniq
expr
: 进行数学运算Example: add 2 and 3expr 2 "+" 3
find
: 搜索文件比如:根据文件名搜索find . -name filename -print
tee
: 将数据输出到标准输出设备(屏幕) 和文件比如:somecommand \| tee outfile
basename file
: 返回不包含路径的文件名比如:basename /bin/tux
将返回tux
dirname file
: 返回文件所在路径比如:dirname /bin/tux
将返回/bin
head file
: 打印文本文件开头几行tail file
: 打印文本文件末尾几行sed
: Sed是一个基本的查找替换程序。可以从标准输入(比如命令管道)读入文本,并将结果输出到标准输出(屏幕)。该命令采用正则表达式(见参考)进行搜索。不要和shell中的通配符相混淆。比如:将linuxfocus
替换为LinuxFocus
:cat text.file \| sed 's/linuxfocus/LinuxFocus/' > newtext.file
awk
: awk 用来从文本文件中提取字段。缺省地,字段分割符是空格,可以使用-F
指定其他分割符。cat file.txt \| awk -F, '{print $1 "," $3 }'
这里我们使用,作为字段分割符,同时打印第一个和第三个字段。如果该文件内容如下:Adam Bor, 34, IndiaKerry Miller, 22, USA
命令输出结果为:Adam Bor, IndiaKerry Miller, USA
2) 概念: 管道, 重定向和 backtick
这些不是系统命令,但是他们真的很重要。
- 管道 (
|
) 将一个命令的输出作为另外一个命令的输入。 - 重定向:将命令的结果输出到文件,而不是标准输出(屏幕)。
>
写入文件并覆盖旧文件>>
加到文件的尾部,保留旧文件内容。
- 反短斜线 (
\
) 使用反短斜线可以将一个命令的输出作为另外一个命令的一个命令行参数。
3) 流程控制
“if” 表达式 如果条件为真则执行then后面的部分:
if ....; then
....
elif ....; then
....
else
....
fi
大多数情况下,可以使用测试命令来对条件进行测试。比如可以比较字符串、判断文件是否存在及是否可读等等…
通常用" [ ] "来表示条件测试。注意这里的空格很重要。要确保方括号的空格。
[ -f "somefile" ] :判断是否是一个文件
[ -x "/bin/ls" ] :判断/bin/ls是否存在并有可执行权限
[ -n "$var" ] :判断$var变量是否有值
[ "$a" = "$b" ] :判断$a和$b是否相等
执行man test
可以查看所有测试表达式可以比较和判断的类型。
直接执行以下脚本:
#!/bin/sh
if [ "$SHELL" = "/bin/bash" ]; then
echo "your login shell is the bash (bourne again shell)"
else
echo "your login shell is not bash but $SHELL"
fi
变量$SHELL包含了登录shell的名称,我们和/bin/bash
进行了比较。
快捷操作符
熟悉C语言的朋友可能会很喜欢下面的表达式:
[ -f "/etc/shadow" ] && echo "This computer uses shadow passwors"
这里 &&
就是一个快捷操作符,如果左边的表达式为真则执行右边的语句。您也可以认为是逻辑运算中的与操作。上例中表示如果/etc/shadow
文件存在则打印” This computer uses shadow passwors”。同样或操作(||
)在shell编程中也是可用的。这里有个例子:
#!/bin/sh
mailfolder=/var/spool/mail/james
[ -r "$mailfolder" ]' '{ echo "Can not read $mailfolder" ; exit 1; }
echo "$mailfolder has mail from:"
grep "^From " $mailfolder
该脚本首先判断mailfolder
是否可读。如果可读则打印该文件中的"From" 一行。如果不可读则或操作生效,打印错误信息后脚本退出。这里有个问题,那就是我们必须有两个命令:
- 打印错误信息
- 退出程序
我们使用花括号以匿名函数的形式将两个命令放到一起作为一个命令使用。一般函数将在下文提及。
不用与和或操作符,我们也可以用if表达式作任何事情,但是使用与或操作符会更便利很多。
case 表达式
可以用来匹配一个给定的字符串,而不是数字。
case ... in
...
) do something ;;
...
esac
让我们看一个例子。 file命令可以辨别出一个给定文件的文件类型,比如:
file lf.gz
这将返回:
lf.gz: gzip compressed data, deflated, original filename,
last modified: Mon Aug 27 23:09:18 2001, os: Unix
我们利用这一点写了一个叫做smartzip的脚本,该脚本可以自动解压bzip2, gzip 和zip 类型的压缩文件:
#!/bin/sh
ftype=`file "$1"`
case "$ftype" in
"$1: Zip archive"*)
unzip "$1" ;;
"$1: gzip compressed"*)
gunzip "$1" ;;
"$1: bzip2 compressed"*)
bunzip2 "$1" ;;
*)
error "File $1 can not be uncompressed with smartzip";;
esac
您可能注意到我们在这里使用了一个特殊的变量$1
。该变量包含了传递给该程序的第一个参数值。也就是说,当我们运行:
smartzip articles.zip
$1
就是字符串 articles.zip
select 表达式
是一种bash的扩展应用,尤其擅长于交互式使用。用户可以从一组不同的值中进行选择。
select var in ... ; do
break
done
.... now $var can be used ....
下面是一个例子:
#!/bin/sh
echo "What is your favourite OS?"
select var in "Linux" "Gnu Hurd" "Free BSD" "Other"; dobreak
done
echo "You have selected $var"
下面是该脚本运行的结果:
What is your favourite OS?
1) Linux
2) Gnu Hurd
3) Free BSD
4) Other
#? 1You have selected Linux
循环表达式
while-loop
while ...; do
....
done
while-loop 将运行直到表达式测试为真。关键字"break" 用来跳出循环。而关键字”continue”用来不执行余下的部分而直接跳到下一个循环。
for-loop
for var in ....; do
....
done
在下面的例子中,将分别打印ABC到屏幕上:
#!/bin/sh
for var in A B C ; do
echo "var is $var"
done
下面是一个更为有用的脚本showrpm,其功能是打印一些RPM包的统计信息:
#!/bin/sh
# list a content summary of a number of RPM packages
# USAGE: showrpm rpmfile1 rpmfile2 ...
# EXAMPLE: showrpm /cdrom/RedHat/RPMS/*.rpm
for rpmpackage in $*; do
if [ -r "$rpmpackage" ];then
echo "=============== $rpmpackage =============="
rpm -qi -p $rpmpackage
else
echo "ERROR: cannot read file $rpmpackage"
fi
done
这里出现了第二个特殊的变量 $*
,该变量包含了所有输入的命令行参数值。如果您运行 showrpm openssh.rpm w3m.rpm webgrep.rpm
,此时 $*
包含了 3 个字符串,即 openssh.rpm
, w3m.rpm
and webgrep.rpm
.
引号
在向程序传递任何参数之前,程序会扩展通配符和变量。这里所谓扩展的意思是程序会把通配符(比如 *
)替换成合适的文件名,它变量替换成变量值。为了防止程序作这种替换,您可以使用引号:让我们来看一个例子,假设在当前目录下有一些文件,两个 jpg 文件, mail.jpg 和 tux.jpg。
#!/bin/sh
echo *.jpg
这将打印出 “mail.jpg tux.jpg” 的结果。
引号 (单引号和双引号)将防止这种通配符扩展:
#!/bin/sh
echo "*.jpg"
echo '\*.jpg'
这将打印 “*.jpg” 两次。
单引号更严格一些。它可以防止任何变量扩展。双引号可以防止通配符扩展但允许变量扩展。
#!/bin/sh
echo $SHELL
echo "$SHELL"
echo '$SHELL'
运行结果为:
/bin/bash
/bin/bash
$SHELL
最后,还有一种防止这种扩展的方法,那就是使用转义字符——反斜杆:
echo \*.jpg
echo $SHELL
这将输出:
*.jpg
$SHELL
Here documents
当要将几行文字传递给一个命令时,here documents 一种不错的方法。对每个脚本写一段帮助性的文字是很有用的,此时如果我们使用那个 here documents 就不必用 echo 函数一行行输出。 一个 “Here document” 以 <<
开始,后面接上一个字符串,这个字符串还必须出现在 here document 的末尾。下面是一个例子,在该例子中,我们对多个文件进行重命名,并且使用 here documents 打印帮助:
#!/bin/sh
# we have less than 3 arguments. Print the help text:
if [ $# -lt 3 ] ; then
cat <
ren -- renames a number of files using sed regular expressions
USAGE: ren 'regexp' 'replacement' files...
EXAMPLE: rename all *.HTM files in *.html:
ren 'HTM$' 'html' *.HTM
HELP
exit 0
fi
OLD="$1"
NEW="$2"
# The shift command removes one argument from the list of
# command line arguments.
shift
shift
# $* contains now all the files:
for file in $*; do
if [ -f "$file" ] ; then
newfile=`echo "$file" | sed "s/${OLD}/${NEW}/g"`
if [ -f "$newfile" ]; thenecho "ERROR: $newfile exists already"
elseecho "renaming $file to $newfile ..."mv "$file" "$newfile"
fi
fi
done
这是一个复杂一些的例子。让我们详细讨论一下。第一个 if 表达式判断输入命令行参数是否小于 3 个 (特殊变量 $#
表示包含参数的个数)。如果输入参数小于 3 个,则将帮助文字传递给 cat
命令,然后由 cat
命令将其打印在屏幕上。打印帮助文字后程序退出。如果输入参数等于或大于 3 个,我们就将第一个参数赋值给变量 OLD
,第二个参数赋值给变量 NEW
。下一步,我们使用 shift
命令将第一个和第二个参数从参数列表中删除,这样原来的第三个参数就成为参数列表 $*
的第一个参数。然后我们开始循环,命令行参数列表被一个接一个地被赋值给变量 $file
。接着我们判断该文件是否存在,如果存在则通过 sed
命令搜索和替换来产生新的文件名。然后将反短斜线内命令结果赋值给 newfile
。这样我们就达到了我们的目的:得到了旧文件名和新文件名。然后使用 mv
命令进行重命名。
函数
如果您写了一些稍微复杂一些的程序,您就会发现在程序中可能在几个地方使用了相同的代码,并且您也会发现,如果我们使用了函数,会方便很多。一个函数是这个样子的:
functionname()
{# inside the body $1 is the first argument given to the function# $2 the second ...body
}
您需要在每个程序的开始对函数进行声明。
下面是一个叫做xtitlebar的脚本,使用这个脚本您可以改变终端窗口的名称。这里使用了一个叫做help的函数。正如您可以看到的那样,这个定义的函数被使用了两次。
#!/bin/sh
# vim: set sw=4 ts=4 et:
help()
{cat <
xtitlebar -- change the name of an xterm, gnome-terminal or kde konsole
USAGE: xtitlebar [-h] "string_for_titelbar"
OPTIONS: -h help text
EXAMPLE: xtitlebar "cvs"
HELP
exit 0
}
# in case of error or if -h is given we call the function help:
[ -z "$1" ] && help
[ "$1" = "-h" ] && help
# send the escape sequence to change the xterm titelbar:
echo -e "33]0;$107"
在脚本中提供帮助是一种很好的编程习惯,这样方便其他用户(和您)使用和理解脚本。
命令行参数
我们已经见过$*
和 $1
, $2
… $9
等特殊变量,这些特殊变量包含了用户从命令行输入的参数。迄今为止,我们仅仅了解了一些简单的命令行语法(比如一些强制性的参数和查看帮助的-h
选项)。但是在编写更复杂的程序时,您可能会发现您需要更多的自定义的选项。通常的惯例是在所有可选的参数之前加一个减号,后面再加上参数值 (比如文件名)。
有好多方法可以实现对输入参数的分析,但是下面的使用case表达式的例子无遗是一个不错的方法。
#!/bin/sh
help()
{cat <
This is a generic command line parser demo.
USAGE EXAMPLE: cmdparser -l hello -f -- -somefile1 somefile2
HELP
exit 0
}
while [ -n "$1" ]; do
case $1 in-h) help;shift 1;; # function help is called-f) opt_f=1;shift 1;; # variable opt_f is set-l) opt_l=$2;shift 2;; # -l takes an argument -> shift by 2--) shift;break;; # end of options-*) echo "error: no such option $1. -h for help";exit 1;;
*) break;;
esac
done
echo "opt_f is $opt_f"
echo "opt_l is $opt_l"
echo "first arg is $1"
echo "2nd arg is $2"
您可以这样运行该脚本:
cmdparser -l hello -f -- -somefile1 somefile2
返回的结果是:
opt_f is 1
opt_l is hello
first arg is -somefile1
2nd arg is somefile2
这个脚本是如何工作的呢?脚本首先在所有输入命令行参数中进行循环,将输入参数与case表达式进行比较,如果匹配则设置一个变量并且移除该参数。根据unix系统的惯例,首先输入的应该是包含减号的参数。
实例
一般编程步骤
现在我们来讨论编写一个脚本的一般步骤。任何优秀的脚本都应该具有帮助和输入参数。并且写一个伪脚本(framework.sh),该脚本包含了大多数脚本都需要的框架结构,是一个非常不错的主意。这时候,在写一个新的脚本时我们只需要执行一下copy命令:
cp framework.sh myscript
然后再插入自己的函数。
让我们再看两个例子:
二进制到十进制的转换
脚本 b2d 将二进制数 (比如 1101) 转换为相应的十进制数。这也是一个用expr
命令进行数学运算的例子:
#!/bin/sh
# vim: set sw=4 ts=4 et:
help()
{cat <
b2h -- convert binary to decimal
USAGE: b2h [-h] binarynum
OPTIONS: -h help text
EXAMPLE: b2h 111010
will return 58
HELP
exit 0
}
error()
{# print an error and exitecho "$1"exit 1
}
lastchar()
{# return the last character of a string in $rvalif [ -z "$1" ]; then# empty stringrval=""returnfi# wc puts some space behind the output this is why we need sed:numofchar=`echo -n "$1" | wc -c | sed 's/ //g' `# now cut out the last charrval=`echo -n "$1" | cut -b $numofchar`
}
chop()
{# remove the last character in string and return it in $rvalif [ -z "$1" ]; then# empty stringrval=""returnfi# wc puts some space behind the output this is why we need sed:numofchar=`echo -n "$1" | wc -c | sed 's/ //g' `if [ "$numofchar" = "1" ]; then# only one char in stringrval=""returnfinumofcharminus1=`expr $numofchar - 1`# now cut all but the last char:rval=`echo -n "$1" | cut -b 0-${numofcharminus1}`
}
while [ -n "$1" ]; do
case $1 in-h) help;shift 1;; # function help is called--) shift;break;; # end of options-*) error "error: no such option $1. -h for help";;
*) break;;
esac
done
# The main program
sum=0
weight=1
# one arg must be given:
[ -z "$1" ] && help
binnum="$1"
binnumorig="$1"
while [ -n "$binnum" ]; do
lastchar "$binnum"
if [ "$rval" = "1" ]; thensum=`expr "$weight" "+" "$sum"`
fi
# remove the last position in $binnum
chop "$binnum"
binnum="$rval"
weight=`expr "$weight" "*" 2`
done
echo "binary $binnumorig is decimal $sum"
该脚本使用的算法是利用十进制和二进制数权值 (1,2,4,8,16,…),比如二进制"10"可以这样转换成十进制:
[ 0 * 1 + 1 * 2 = 2 ]
为了得到单个的二进制数我们是用了 lastchar 函数。该函数使用 wc –c 计算字符个数,然后使用 cut 命令取出末尾一个字符。Chop 函数的功能则是移除最后一个字符。
文件循环程序
或许您是想将所有发出的邮件保存到一个文件中的人们中的一员,但是在过了几个月以后,这个文件可能会变得很大以至于使对该文件的访问速度变慢。下面的脚本 rotatefile 可以解决这个问题。这个脚本可以重命名邮件保存文件(假设为 outmail)为 outmail.1,而对于 outmail.1 就变成了 outmail.2 等等等等…
#!/bin/sh
# vim: set sw=4 ts=4 et:
ver="0.1"
help()
{cat <
rotatefile -- rotate the file name
USAGE: rotatefile [-h] filename
OPTIONS: -h help text
EXAMPLE: rotatefile out
This will e.g rename out.2 to out.3, out.1 to out.2, out to out.1
and create an empty out-file
The max number is 10
version $ver
HELP
exit 0
}
error()
{echo "$1"exit 1
}
while [ -n "$1" ]; do
case $1 in-h) help;shift 1;;--) break;;-*) echo "error: no such option $1. -h for help";exit 1;;
*) break;;
esac
done
# input check:
if [ -z "$1" ]; then
error "ERROR: you must specify a file, use -h for help"
fi
filen="$1"
# rename any .1 , .2 etc file:
for n in 9 8 7 6 5 4 3 2 1; do
if [ -f "$filen.$n" ]; thenp=`expr $n + 1`echo "mv $filen.$n $filen.$p"mv $filen.$n $filen.$p
fi
done
# rename the original file:
if [ -f "$filen" ]; then
echo "mv $filen $filen.1"
mv $filen $filen.1
fi
echo touch $filen
touch $filen
这个脚本是如何工作的呢?在检测用户提供了一个文件名以后,我们进行一个 9 到 1 的循环。文件 9 被命名为 10,文件 8 重命名为 9 等等。循环完成之后,我们将原始文件命名为文件 1 同时建立一个与原始文件同名的空文件。
调试
最简单的调试命令当然是使用 echo 命令。您可以使用 echo 在任何怀疑出错的地方打印任何变量值。这也是绝大多数的 shell 程序员要花费 80% 的时间来调试程序的原因。Shell 程序的好处在于不需要重新编译,插入一个 echo 命令也不需要多少时间。
shell 也有一个真实的调试模式。如果在脚本 “strangescript” 中有错误,您可以这样来进行调试:
sh -x strangescript
这将执行该脚本并显示所有变量的值。
shell还有一个不需要执行脚本只是检查语法的模式。可以这样使用:
sh -n your_script
这将返回所有语法错误。
Bash 脚本
阿汤哥的程序之路于 2021-05-26 10:21:54 发布
什么是 Bash
简介
Bash(GNU Bourne-Again Shell)是一个为 GNU 计划编写的 Unix shell,它是许多 Linux 平台默认使用的 shell。
shell 是一个命令解释器,是介于操作系统内核与用户之间的一个绝缘层。准确地说,它也是能力很强的计算机语言,被称为解释性语言或脚本语言。它可以通过将系统调用、公共程序、工具和编译过的二进制程序”粘合“在一起来建立应用,这是大多数脚本语言的共同特征,所以有时候脚本语言又叫做“胶水语言”。
事实上,所有的 UNIX 命令和工具再加上公共程序,对于 shell 脚本来说,都是可调用的。Shell 脚本对于管理系统任务和其它的重复工作的例程来说,表现的非常好,根本不需要那些华而不实的成熟紧凑的编译型程序语言。
运行 Bash 脚本的方式:
#!/bin/bash
#这一行是表示使用 /bin/bash 作为脚本的解释器
#这行要放在脚本的行首并且不要省略。# 使用shell来执行
sh hello.sh# 使用bash来执行
bash hello.sh# 使用.来执行
. ./hello.sh# 使用source来执行
source hello.sh# 还可以赋予脚本所有者执行权限,允许该用户执行该脚本
chmod u+rx hello.sh
./hello.sh
bash特殊字符(上)
注释(#)
行首以 # 开头(除#!之外)的是注释。#! 是用于指定当前脚本的解释器,我们这里为 bash,且应该指明完整路径,所以为 /bin/bash
分号(;)
使用分号 ; 可以在同一行上写两个或两个以上的命令。
点号(.)
等价于 source 命令
bash 中的 source 命令用于在当前 bash 环境下读取并执行 FileName.sh 中的命令。
source test.sh. test.sh
引号
双引号(")
“STRING” 将会阻止(解释)STRING 中大部分特殊的字符。后面的实验会详细说明。
单引号(’)
‘STRING’ 将会阻止 STRING 中所有特殊字符的解释,这是一种比使用"更强烈的形式。后面的实验会详细说明。
反引号(`)
命令替换
反引号中的命令会优先执行,如:
cp `mkdir back` test.sh back
ls
先创建了 back 目录,然后复制 test.sh 到 back 目录。
冒号(:)
空命令
等价于“NOP”(no op,一个什么也不干的命令)。也可以被认为与 shell 的内建命令 true 作用相同。“:”命令是一个 bash 的内建命令,它的退出码(exit status)是(0)。
#!/bin/bashwhile :
doecho "endless loop"
done
等价于
#!/bin/bashwhile true
doecho "endless loop"
done
可以在 if/then 中作占位符:
#!/bin/bashcondition=5if [ $condition -gt 0 ]
#gt表示greater than,也就是大于,同样有-lt(小于),-eq(等于)
then : # 什么都不做,退出分支
elseecho "$condition"
fi
变量扩展/子串替换
在与 > 重定向操作符结合使用时,将会把一个文件清空,但是并不会修改这个文件的权限。如果之前这个文件并不存在,那么就创建这个文件。
: > test.sh # 文件“test.sh”现在被清空了
# 与 cat /dev/null > test.sh 的作用相同
# 然而,这并不会产生一个新的进程, 因为“:”是一个内建命令
在与 >> 重定向操作符结合使用时,将不会对预先存在的目标文件 : >> target_file 产生任何影响。如果这个文件之前并不存在,那么就创建它。
问号(?)
测试操作符
在一个双括号结构中,? 就是 C 语言的三元操作符,如:
vim test.sh
输入如下代码,并保存:
#!/bin/basha=10(( t=a<50?8:9 ))echo $t
运行测试
bash test.sh
8
美元符号($)
引用变量
bash特殊字符(下)
小括号(( ))
在括号中的变量,由于是在子 shell 中,所以对于脚本剩下的部分是不可用的。父进程,也就是脚本本身,将不能够读取在子进程中创建的变量,也就是在子 shell 中创建的变量。如:
vim test20.sh
输入代码:
#!/bin/bash( a=321; )
运行代码:
bash test20.sh
在圆括号中 a 变量,更像是一个局部变量。
初始化数组
创建数组
vim test21.sh
输入代码:
#!/bin/basharr=(1 4 5 7 9 21)
echo ${arr[3]} # get a value of arr
运行代码:
bash test21.sh
7
大括号({ })
文件名扩展
复制 t.txt 的内容到 t.back 中
vim test22.sh
输入代码:
#!/bin/bashif [ ! -w 't.txt' ];
thentouch t.txt
fi
echo 'test text' >> t.txt
cp t.{txt,back}
运行代码:
bash test22.sh
查看运行结果:
ls
cat t.txt
cat t.back
注意: 在大括号中,不允许有空白,除非这个空白被引用或转义。
代码块
代码块,又被称为内部组,这个结构事实上创建了一个匿名函数(一个没有名字的函数)。然而,与“标准”函数不同的是,在其中声明的变量,对于脚本其他部分的代码来说还是可见的。
vim test23.sh
输入代码:
#!/bin/bash{ a=321; }
echo "a = $a"
运行代码:
bash test23.sh
a = 321
变量 a 的值被更改了。
中括号([ ])
条件测试
条件测试表达式放在 [ ] 中。下列练习中的 -lt (less than)表示小于号。
vim test24.sh
输入代码:
#!/bin/basha=5
if [ $a -lt 10 ]
thenecho "a: $a"
elseecho 'a>=10'
fi
运行代码:
bash test24.sh
a: 5
数组元素
在一个 array 结构的上下文中,中括号用来引用数组中每个元素的编号。
vim test25.sh
输入代码:
#!/bin/basharr=(12 22 32)
arr[0]=10
echo ${arr[0]}
运行代码:
bash test25.sh
10
尖括号(< 和 >)
重定向
test.sh > filename:重定向 test.sh 的输出到文件 filename 中。如果 filename 存在的话,那么将会被覆盖。
test.sh &> filename:重定向 test.sh 的 stdout(标准输出)和 stderr(标准错误)到 filename 中。
test.sh >&2:重定向 test.sh 的 stdout 到 stderr 中。
test.sh >> filename:把 test.sh 的输出追加到文件 filename 中。如果 filename 不存在的话,将会被创建。
竖线(|)
管道
分析前边命令的输出,并将输出作为后边命令的输入。这是一种产生命令链的好方法。
破折号(-)
波浪号(~)
特殊变量
位置参数
从命令行传递到脚本的参数:$0,$1,$2,$3…
$0 就是脚本文件自身的名字,$1 是第一个参数,$2 是第二个参数,$3 是第三个参数,然后是第四个。9 之 后 的 位 置 参 数 就 必 须 用 大 括 号 括 起 来 了 , 比 如 , 9 之后的位置参数就必须用大括号括起来了,比如,9之后的位置参数就必须用大括号括起来了,比如,{10},11 , {11},11,{12}。
$# : 传递到脚本的参数个数
$* : 以一个单字符串显示所有向脚本传递的参数。与位置变量不同,此选项参数可超过 9 个
$$ : 脚本运行的当前进程 ID 号
$! : 后台运行的最后一个进程的进程 ID 号
$@ : 与 $* 相同,但是使用时加引号,并在引号中返回每个参数
$: 显示 shell 使用的当前选项,与 set 命令功能相同
$? : 显示最后命令的退出状态。 0 表示没有错误,其他任何值表明有错误。
位置参数实例
vim test30.sh
1
#!/bin/bash# 作为用例, 调用这个脚本至少需要10个参数, 比如:
# bash test.sh 1 2 3 4 5 6 7 8 9 10
MINPARAMS=10echoecho "The name of this script is \"$0\"."echo "The name of this script is \"`basename $0`\"."echoif [ -n "$1" ] # 测试变量被引用.
then
echo "Parameter #1 is $1" # 需要引用才能够转义"#"
fiif [ -n "$2" ]
then
echo "Parameter #2 is $2"
fiif [ -n "${10}" ] # 大于$9的参数必须用{}括起来.
then
echo "Parameter #10 is ${10}"
fiecho "-----------------------------------"
echo "All the command-line parameters are: "$*""if [ $# -lt "$MINPARAMS" ]
thenechoecho "This script needs at least $MINPARAMS command-line arguments!"
fiechoexit 0
运行代码:
bash test30.sh 1 2 10The name of this script is "test.sh".
The name of this script is "test.sh".Parameter #1 is 1
Parameter #2 is 2
-----------------------------------
All the command-line parameters are: 1 2 10This script needs at least 10 command-line arguments!
基本运算符
算数运算符
vim test.sh
1
#!/bin/basha=10
b=20val=`expr $a + $b`
echo "a + b : $val"val=`expr $a - $b`
echo "a - b : $val"val=`expr $a \* $b`
echo "a * b : $val"val=`expr $b / $a`
echo "b / a : $val"val=`expr $b % $a`
echo "b % a : $val"if [ $a == $b ]
thenecho "a == b"
fi
if [ $a != $b ]
thenecho "a != b"
fi
运行
bash test.sha + b : 30
a - b : -10
a * b : 200
b / a : 2
b % a : 0
a != b
原生 bash 不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。
expr 是一款表达式计算工具,使用它能完成表达式的求值操作。
注意使用的反引号(esc 键下边)
表达式和运算符之间要有空格 $a + $b 写成 a + a+a+b 不行
条件表达式要放在方括号之间,并且要有空格 [ a = = b ] 写成 [ b ] 写成 [ b ] 写成 [ a = = a == b ] 写 成 [ b ] 写成 [b]写成[a== a==b]写成[b]写成[b]写成[a==b] 不行
乘号(*)前边必须加反斜杠()才能实现乘法运算
关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
#!/bin/basha=10
b=20if [ $a -eq $b ]
thenecho "$a -eq $b : a == b"
elseecho "$a -eq $b: a != b"
fi
逻辑运算符
#!/bin/bash
a=10
b=20if [[ $a -lt 100 && $b -gt 100 ]]
thenecho "return true"
elseecho "return false"
fiif [[ $a -lt 100 || $b -gt 100 ]]
thenecho "return true"
elseecho "return false"
fi
字符串运算符
#!/bin/basha="abc"
b="efg"if [ $a = $b ]
thenecho "$a = $b : a == b"
elseecho "$a = $b: a != b"
fi
if [ -n $a ]
thenecho "-n $a : The string length is not 0"
elseecho "-n $a : The string length is 0"
fi
if [ $a ]
thenecho "$a : The string is not empty"
elseecho "$a : The string is empty"
fi
结果
abc = efg: a != b
-n abc : The string length is not 0
abc : The string is not empty
文件测试运算符
实例:
#!/bin/bashfile="/home/shiyanlou/test.sh"
if [ -r $file ]
thenecho "The file is readable"
elseecho "The file is not readable"
fi
if [ -e $file ]
thenecho "File exists"
elseecho "File not exists"
fi
结果
The file is readable
File exists
思考
浮点运算,比如实现求圆的面积和周长。
expr 只能用于整数计算,可以使用 bc 或者 awk 进行浮点数运算。
#!/bin/bash
radius=2.4
pi=3.14159
girth=$(echo "scale=4; 3.14 * 2 * $radius" | bc)
area=$(echo "scale=4; 3.14 * $radius * $radius" | bc)
echo "girth=$girth"
echo "area=$area"
以上代码如果想在环境中运行,需要先安装 bc。
sudo apt-get update
sudo apt-get install bc
流程控制
if else
if
if 语句语法格式:
if condition
thencommand1command2...commandN
fi
if else
if else 语法格式:
if condition
thencommand1command2...commandN
elsecommand
fi
if-elif-else 语法格式:
if condition1
thencommand1
elif condition2
thencommand2
elsecommandN
fi
for 循环
for 循环一般格式为:
for var in item1 item2 ... itemN
docommand1command2...commandN
done
while 语句
while 循环用于不断执行一系列命令,也用于从输入文件中读取数据;命令通常为测试条件。其格式为:
while condition
docommand
done
无限循环
无限循环语法格式:
while :
docommand
done
或者
while true
docommand
done
或者
for (( ; ; ))
until 循环
until 循环执行一系列命令直至条件为真时停止。 until 循环与 while 循环在处理方式上刚好相反。 一般 while 循环优于 until 循环,但在某些时候—也只是极少数情况下,until 循环更加有用。 until 语法格式:
until condition
docommand
done
case
Shell case 语句为多选择语句。可以用 case 语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。case 语句格式如下:
case 值 in
模式1)command1command2...commandN;;
模式2)command1command2...commandN;;
esac
取值后面必须为单词 in,每一模式必须以右括号结束。取值可以为变量或常数。匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;;。
取值将检测匹配的每一个模式。一旦模式匹配,则执行完匹配模式相应命令后不再继续其他模式。如果无一匹配模式,使用星号 * 捕获该值,再执行后面的命令。
下面的脚本提示输入 1 到 4,与每一种模式进行匹配:
echo 'Enter a number between 1 and 4:'
echo 'The number you entered is:'
read aNum
case $aNum in1) echo 'You have chosen 1';;2) echo 'You have chosen 2';;3) echo 'You have chosen 3';;4) echo 'You have chosen 4';;*) echo 'You did not enter a number between 1 and 4';;
esac
输入不同的内容,会有不同的结果,例如:
Enter a number between 1 and 4:
The number you entered is:
3
You have chosen 3
跳出循环
在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环,Shell 使用两个命令来实现该功能:break 和 continue。
break 命令
break 命令允许跳出所有循环(终止执行后面的所有循环)。
下面的例子中,脚本进入死循环直至用户输入数字大于 5。要跳出这个循环,返回到 shell 提示符下,需要使用 break 命令。
#!/bin/bash
while :
doecho -n "Enter a number between 1 and 5:"read aNumcase $aNum in1|2|3|4|5) echo "The number you entered is $aNum!";;*) echo "The number you entered is not between 1 and 5! game over!"break;;esac
done
执行以上代码,输出结果为:
Enter a number between 1 and 5:3
The number you entered is 3!
Enter a number between 1 and 5:7
The number you entered is not between 1 and 5! game over!
continue
continue 命令与 break 命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。 对上面的例子进行修改:
#!/bin/bash
while :
doecho -n "Enter a number between 1 and 5: "read aNumcase $aNum in1|2|3|4|5) echo "The number you entered is $aNum!";;*) echo "The number you entered is not between 1 and 5!"continueecho "game over";;esac
done
运行代码发现,当输入大于 5 的数字时,该例中的循环不会结束,语句 echo “Game is over!” 永远不会被执行。
via:
-
非常好的 BASH 脚本编写教程_bash脚本怎么写-CSDN博客as good as well于 2017-08-04 22:04:28 发布
https://blog.csdn.net/liangshoulong/article/details/76695811 -
Bash Shell 详解:命令、脚本与流程控制-CSDN博客 阿汤哥的程序之路于 2021-05-26 10:21:54 发布
https://blog.csdn.net/tangsiqi130/article/details/117229093 -
高级 Bash 脚本编程指南_Linux - 蓝桥云课
https://www.lanqiao.cn/courses/944
相关文章:
Bash 脚本教程
注:本文为 “Bash 脚本编写” 相关文章合辑。 BASH 脚本编写教程 as good as well于 2017-08-04 22:04:28 发布 这里有个老 American 写的 BASH 脚本编写教程,非常不错,至少没接触过 BASH 的也能看懂! 建立一个脚本 Linux 中有…...
SQL创建和操纵表
本文介绍创建、更改和删除表的基本知识。 1. 创建表 SQL 不仅用于表数据操纵,而且还用来执行数据库和表的所有操作,包括表本身的创建和处理。一般有两种创建表的方法: 多数DBMS 都具有交互式创建和管理数据库表的工具;表也可以…...
1.微服务灰度发布(方案设计)
前言 微服务架构中的灰度发布(也称为金丝雀发布或渐进式发布)是一种在不影响现有用户的情况下,逐步将新版本的服务部署到生产环境的策略。通过灰度发布,你可以先将新版本的服务暴露给一小部分用户或特定的流量,观察其…...
QT笔记- QTreeView + QFileSystemModel 当前位置的保存与恢复 #选中 #保存当前索引
保存当前位置 QString currentPath model->filePath(view->currentIndex()); // 获得当前位置路径 恢复位置 view->setCurrentIndex(model->index(currentPath)); // 设置此路径所在位置为当前位置...
LeetCode - Google 校招100题 第6天 回溯法(Backtracking) (8题)
欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/144743505 LeetCode 合计最常见的 112 题: 校招100题 第1天 链表(List) (19题)校招100题 第2天 树(Tree) (21题)校招100题 第3天 动态规划(DP) (20题)...
k8s,service如何找到容器
Kubernetes之所以需要Service,一方面是因为Pod的IP不是固定的,另一方面则是因为一组Pod实例之间总会有负载均衡的需求 被selector选中的Pod,就称为Service的Endpoints,查看方式: kubectl get endpoints hostnames需要…...
计算机的错误计算(一百九十二)
摘要 用两个大模型计算 csc(0.999), 其中,0.999是以弧度为单位的角度,结果保留5位有效数字。两个大模型均给出了 Python代码与答案。但是,答案是错误的。 例1. 计算 csc(0.999), 其中,0.999是以弧度为单位的角度,结…...
金仓数据库安装-Kingbase v9-centos
在很多年前有个项目用的金仓数据库,上线稳定后就没在这个项目了,只有公司的开发环境还在维护,已经好多年没有安装过了,重温一下金仓数据库安装,体验一下最新版本,也做一个新版本的试验环境; 一、…...
深入解析 Java 中的 getDeclaredMethods() 方法:使用与原理全攻略
在 Java 的反射机制中,getDeclaredMethods() 是一个非常重要的方法,它允许我们获取类中声明的所有方法(包括公共、私有、保护以及默认访问权限的方法)。通过这个方法,我们可以动态地分析和操作类的行为,这在…...
Dockerfile的用法
Dockerfile的用法 示例 `Dockerfile`使用 `Dockerfile` 创建 Docker 镜像`Dockerfile` 指令详解其他常用指令总结Dockerfile 是一个文本文件,包含了用于创建 Docker 镜像的一系列指令。这些指令描述了镜像的基础、所安装的软件、文件的复制、环境变量的设置以及其他配置。下面…...
Gmsh有限元网格剖分(Python)---点、直线、平面的移动
Gmsh有限元网格剖分(Python)—点、直线、平面的移动和旋转 最近在学习有限元的网格剖分算法,主要还是要参考老外的开源Gmsh库进行,写一些博客记录下学习过程,方便以后回忆嘞。 Gmsh的官方英文文档可以参考:gmsh.pdf 但咋就说&a…...
AI的进阶之路:从机器学习到深度学习的演变(三)
(承接上集:AI的进阶之路:从机器学习到深度学习的演变(二)) 四、深度学习(DL):机器学习的革命性突破 深度学习(DL)作为机器学习的一个重要分支&am…...
如何通过 360 驱动大师检查自己电脑上的显卡信息
在深入探讨如何查看显卡信息之前,首先需要了解显卡的基本概念。显卡(Graphics Processing Unit, GPU),是计算机中负责处理图形输出到显示器的重要硬件。根据其集成度和性能,显卡通常被分为两类: 集成显卡&…...
数据仓库工具箱—读书笔记02(Kimball维度建模技术概述04、使用一致性维度集成)
Kimball维度建模技术概述 记录一下读《数据仓库工具箱》时的思考,摘录一些书中关于维度建模比较重要的思想与大家分享🤣🤣🤣 第二章前言部分作者提到:技术的介绍应该通过涵盖各种行业的熟悉的用例展开(赞同…...
.net framework wpf 打包免安装exe文件
1、打开所在项目csproj文件添加以下内容: <Target Name"AfterResolveReferences"><ItemGroup><EmbeddedResource Include"(ReferenceCopyLocalPaths)" Condition"%(ReferenceCopyLocalPaths.Extension) .dll"><…...
瑞吉外卖项目学习笔记(八)修改菜品信息、批量启售/停售菜品
瑞吉外卖项目学习笔记(一)准备工作、员工登录功能实现 瑞吉外卖项目学习笔记(二)Swagger、logback、表单校验和参数打印功能的实现 瑞吉外卖项目学习笔记(三)过滤器实现登录校验、添加员工、分页查询员工信息 瑞吉外卖项目学习笔记(四)TableField(fill FieldFill.INSERT)公共字…...
Oracle 日常巡检
1. 检查服务器状态 1.1. CPU使用情况 1.1.1. top top 命令是 Linux 和 Unix 系统中用于显示实时系统状态的工具,特别是对于监控 CPU 和内存的使用非常有用。 在命令行中输入 top,top 会显示一个实时更新的界面,其中包含系统的关键指标&am…...
CS 144 check7: putting it all together
Exercises 经验:两边的TCP连接建立得尽快,如果服务器端启动了,客户端没有启动就连不上。。 服务器端: 客户端: 文件收发测试: 参考: CS 144CS144 | Winter 2024, Lab 0~7 记录࿰…...
springboot数据校验报错
目录 报错信息 原因 解决 报错信息 springboot在进行数据校验的时候ConfigurationProperties注解形式下Email报错 Caused by: javax.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint javax.validation.constraints.Email valid…...
mapbox基础,加载天地图矢量底图
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象…...
SLAM/数字图象处理基础
概念 视差:相同特征的不同深度估计的偏差 BoW,DBoW,DBoW2的区别是什么 Bag of Words (BoW)、DBoW(Dynamic Bag of Words)和DBoW2是用于图像处理和计算机视觉中的不同特征表示和匹配方法。它们之间的主要区别如下&am…...
修改vue-element-admin,如何连接我们的后端
改哪几个文件就可以连接我们后端 主要就这四个 main.js,屏蔽这个或者删除 vue-config 最后两个文件改下端口即可 这样基本就能发了,但是还要改下 改成api 然后还要修改request.js 这里改成我们返回的状态码 我讲一个东西很容易就懂了&…...
基于PLC的采摘机械手系统(论文+源码)
1系统方案设计 本次设计围绕基于PLC的采摘机械手系统进行设计, PLC即可编程控制器其是一种常见的微处理器,本次拟采用西门子是S7-200 PLC,一方面对整个设计从器件选型到I/O分配,图纸绘制等进行设计,另一方面还通过组态…...
使用ArcGIS/ArcGIS pro绘制六边形/三角形/菱形渔网图
在做一些尺度分析时,经常会涉及到对研究区构建不同尺度的渔网进行分析,渔网的形状通常为规则四边形。构建渔网的方法也很简单,使用ArcGIS/ArcGIS Pro工具箱中的【创建渔网/CreateFishnet】工具来构建。但如果想构建其他形状渔网进行相关分析&…...
【5/6 面向应用相关的优化 网卡实现及评估 】
5 面向应用相关的优化 面对数据中心多样化的部署需求和应用场景,如分布式存储、多租户性能隔离等,构建高性能的RDMA系统需要仔细选择传输模式和通信原语以充分发挥其性能优势,并调整软硬件结构进行适配.整体手段:在软件层面结合R…...
如何识别钓鱼邮件和诈骗网站?(附网络安全意识培训PPT资料)
识别钓鱼邮件和诈骗网站是网络安全中的一个重要环节。以下是一些识别钓鱼邮件和诈骗网站的方法: 识别钓鱼邮件: 检查发件人地址: 仔细查看发件人的电子邮件地址,看是否与官方域名一致。 检查邮件内容: 留意邮件中是否…...
TOGAF之架构标准规范-业务架构
TOGAF标准规范中,业务架构阶段的主要工作是开发支持架构愿景的业务架构。 如上所示,业务架构(Business Architecture)在TOGAF标准规范中处于B阶段,该阶段的主要内容包括阶段目标、阶段输入、流程步骤、架构方法。 阶段…...
嵌入式轻量级开源操作系统:HeliOS的使用
嵌入式轻量级开源操作系统:HeliOS的使用 📍项目地址:https://github.com/heliosproj/HeliOS HeliOS项目是一个社区交付的开源项目,用于构建和维护HeliOS嵌入式操作系统(OS)。HeliOS是一个功能齐全的操作系统࿰…...
mysql 数据库迁移到达梦数据库
1.windows安装达梦数据库,去官网下载 dm8 进行安装,安装后,可以使用管理工具管理数据 使用迁移工具对数据进行迁移; 2.使用php 或者 thinkphp连接达梦数据库 2.1、先PHP开启DM扩展 从达梦数据库安装目录下drivers/php_pdo 复制对…...
Java中的异常处理机制
今天想和大家探讨Java中的异常处理机制。异常处理是任何编程语言中不可或缺的一部分,它帮助我们处理程序运行时可能出现的错误,确保程序的健壮性和稳定性。Java作为一种强类型、面向对象的编程语言,提供了一套完整的异常处理框架。 1. 异常的…...
iOS 苹果开发者账号: 查看和添加设备UUID 及设备数量
参考链接:苹果开发者账号下添加新设备UUID - 简书 如果要添加新设备到 Profiles 证书里: 1.登录开发者中心 Sign In - Apple 2.找到证书设置: Certificate,Identifiers&Profiles > Profiles > 选择对应证书 edit &g…...
数据仓库工具箱—读书笔记02(Kimball维度建模技术概述03、维度表技术基础)
Kimball维度建模技术概述 记录一下读《数据仓库工具箱》时的思考,摘录一些书中关于维度建模比较重要的思想与大家分享🤣🤣🤣 第二章前言部分作者提到:技术的介绍应该通过涵盖各种行业的熟悉的用例展开(赞同…...
Linux中常用的Shell脚本(运维+常用)汇总
废话不多说,直接上干货! 一、运维脚本 (1)监控CPU和内存的使用情况 #!/bin/bashcpu_threshold80 mem_threshold80# 获取CPU和内存使用率 cpu_usage$(top -bn1 | grep "Cpu(s)" | sed "s/.*, *\([0-9.]*\)%* id.…...
Java 方法注释:规范、实用和高质量的写法
目录 为什么要注释方法? 方法注释的基本要求 Javadoc 注释格式 示例:一个计算圆面积的方法 代码示例 注释分析 如何写出高质量的 Java 方法注释? 1. 关注可读性 2. 使用 Javadoc 格式 3. 描述异常 4. 适当的解释复杂的算法 5. 避…...
解决JIRA、Confluence用户自动注销、反复登录的问题
一、问题描述:当工作从从confluence里面打开jira的时候,在回到confluence时候,就自动退出了,需要账号密码登录重复登录,使人十分厌恶。 二、原因分析: 访问 JIRA、Confluence 或任何其他具有相同域或 IP 上…...
Python9-作业2
记录python学习,直到学会基本的爬虫,使用python搭建接口自动化测试就算学会了,在进阶webui自动化,app自动化 python基础8-灵活运用顺序、选择、循环结构 作业2九九乘法表三种方式打印九九乘法表使用两个嵌套循环使用列表推导式和…...
基于c语言的union、字符串、格式化输入输出
结构体之共用体union 共用体也叫联合体,其关键词为union 与结构体不同的是,共用体所开辟的存储空间仅仅为其中最长类型变量的存储空间而不是全部变量的存储空间,由于同一内存单元在同一时间内只能存放其中一种的数据类型,因此在每…...
SpringCloudAlibaba实战入门之路由网关Gateway初体验(十)
Spring Cloud 原先整合 Zuul 作为网关组件,Zuul 由 Netflix 公司提供的,现在已经不维护了。后面 Netflix 公司又出来了一个 Zuul2.0 网关,但由于一直没有发布稳定版本,所以 Spring Cloud 等不及了就自己推出一个网关,已…...
活着就好20241227
亲爱的朋友们,大家早上好!🌞 今天是27号,星期五,2024年12月的第二十七天,同时也是第51周的第五天,农历甲辰[龙]年十一月初二十三日。在这晨光渐浓的美好时刻,愿那温暖而明媚的阳光洒…...
robotframework中的测试套件
一. 简介 本文简单来了解一下,robotframework中的测试套件。 二. robotframework中测试套件 1. 什么是测试套件? 测试套件(Test Suite) 是一组相关测试用例的集合。每个测试套件通常代表一个特定的功能模块、系统组件或业务流程…...
Echarts连接数据库,实时绘制图表详解
文章目录 Echarts连接数据库,实时绘制图表详解一、引言二、步骤一:环境准备与数据库连接1、环境搭建2、数据库连接 三、步骤二:数据获取与处理1、查询数据库2、数据处理 四、步骤三:ECharts图表配置与渲染1、配置ECharts选项2、动…...
【QED】爱丽丝与混沌的无尽海
文章目录 题目题目描述输入输出格式数据范围测试样例 思路代码复杂度分析时间复杂度空间复杂度 题目 题目链接🔗 题目描述 如图所示,爱丽丝在一个3x3的迷宫之中,每个方格中标有 1 − 9 1-9 1−9各不相同的数字,爱丽丝可以从一格…...
CHM助手 >> 如何安装CHM助手
1 如何安装CHM助手 下载CHM助手.ezip,下载地址打开EverEdit,选择主菜单“扩展 -> 扩展管理 -> 从本地文件安装扩展”,在弹出的文件浏览窗口中选择插件安装包,如下图所示: 🕮说明: …...
硬件设计:LVDS电平标准
什么是LVDS? LVDS(Low-Voltage Differential Signaling)是一种高速、低功耗的差分信号传输标准。它通过一对差分信号线(通常是两根互补信号线)来传输数据,广泛应用于高速数字通信领域。 LVDS 的核心特点 低…...
宝塔-firefox(Docker应用)-构建自己的Web浏览器
安装基础软件 宝塔中安装firefox(Docker应用) 。宝塔中需要先安装docker及docker-composefirefox配置安装 点击firefox应用,选择【安装配置】点击右边绿色按钮,进行安装,这一步等待docker-compose根据你的配置初始化docker应用 等待安装 …...
微信小程序-基于Vant Weapp UI 组件库的Area 省市区选择
Area 省市区选择,省市区选择组件通常与 弹出层 组件配合使用。 areaList 格式 areaList 为对象结构,包含 province_list、city_list、county_list 三个 key。 每项以地区码作为 key,省市区名字作为 value。地区码为 6 位数字,前两…...
宏转录组+HiFi宏基因组:揭示厌氧消化中的碳流和能量转换
厌氧消化是一种重要的工程生物技术,对有机废物的资源回收和可再生能源的生产起着关键作用。然而,由于对未培养的厌氧菌及其适应环境变化的能力了解有限,这限制了该技术的优化和生物气生产的可持续性。今天小编带大家看一篇发表在《Microbiome…...
【VSCode】工作区及设置
【VSCode】工作区及设置 VSCode介绍工作区设置 VSCode介绍 Visual Studio Code(简称VSCode)是一个由微软开发的免费、开源的代码编辑器,以下是VSCode的一些功能及特性: 编辑器核心: 多文档界面:VSCode允许…...
瀚高数据库
文章目录 瀚高数据库安装瀚高数据库快速入门遇到的问题总结 瀚高数据库 瀚高数据库(HanGaoDB)是一款在分布式存储、高并发处理和高可用性方面表现优异的数据库,特别适用于大数据、高吞吐量、高并发的应用场景。它结合了传统 SQL 数据库和分布…...
xterm遇到的问题及解决方案
xterm遇到的问题及解决方案 /r插入终端导致的之后插入的数据覆盖了改行头部的数据 问题说明 如图所示,当在一行输入的候,输入的l插入到了改行的头部。 查看ws返回数据 可见ws返回的信息存在\r字符,在xterm.js中\r是回车字符的意思&…...