shell脚本基础之处理脚本输入

news2024/12/25 9:26:15

处理输入

    • 命令行参数
      • 读取参数
      • 读取脚本名
      • 测试参数
    • 特殊参数变量
      • 参数统计
      • 获取所有参数
      • 移动变量
    • 处理选项
      • 查找选项
        • 处理简单选项
        • 分离选项和参数
        • 处理带值的选项
      • getopt 命令
        • 命令格式
        • 在脚本中使用getopt
      • getopts命令
    • 脚本选项标准化
    • 获取用户的输入
      • 基本的读取
      • 超时
      • 隐藏式读取
      • 文件中读取

在此之前我们已经学习了编写脚本,处理数据、变量和系统文件。有时,我们编写的脚本还得能够与使用者进行交互。bash shell提供了一些不同的方法来从用户处获得数据,包括 命令行参数(添加在命令后的数据)、命令行选项(可修改命令行为的单个字母)以及直接从键盘读取输入的能力,在下面我们都会一一学习

命令行参数

  • 向shell脚本传递数据的最基本方法是使用命令行参数。命令行参数允许在运行脚本时向命令行添加参数,如下:
./test01 5 2
  • 上例向脚本test01 传递了两个命令行参数(5和30)。脚本会通过特殊的变量来处理命令行参数

读取参数

  • bash shell会将这些被称为位置参数(positional parameter)的特殊变量分配给输入到命令行中的所有参数。这也包括shell所执行的脚本名称。位置参数变量是标准的数字:$0是程序名,$1是第一个参数,$2是第二个参数,依次类推,直到第九个参数$9,如下:
#!/bin/bash
var1=1
for (( number = 1; number <= $1 ; number++ ))
do
        var1=$[ $var1 * $number ]
done
echo "计算结果为:$var1"

在这里插入图片描述

  • 可以在shell脚本中像使用其他变量一样使用$1变量。shell脚本会自动将命令行参数的值分配给变量,不需要再作任何处理
  • 如果需要输入更多的命令行参数,则每个参数都必须用空格分开,如下:
#!/bin/bash

total=$[ $1 + $2 ]
echo "参数1为:$1"
echo "参数2为:$2"
echo "总值为:$total"

在这里插入图片描述

  • 命令行上也可以传递文本字符串参数,但是碰到包含空格的字符串需要注意下述问题,如下:
#!/bin/bash
echo "您好!$1,欢迎登录系统!!"

在这里插入图片描述

  • 每个参数都是用空格分隔的,所以shell会将空格当成两个值的分隔符。要在参数值中包含空格,必须要用引号(单引号或双引号均可),如下:

在这里插入图片描述

  • 注意:将文本字符串作为参数传递时,引号并非数据的一部分。它们只是表明数据的起止位置
  • 当脚本需要的命令行参数不止9个,我们还是可以处理的,但是需要稍微修改一下变量名。在第9个变量之后,你必须在变量数字周围加上花括号{},如下:
#!/bin/bash

total=$[ ${10} + ${11} ]
echo "第10个参数为:${10}"
echo "第11个参数为:${11}"
echo "合计值为:$total"

在这里插入图片描述

读取脚本名

  • 可以用**$0参数**获取shell在命令行启动的脚本名。这在我们后续进行一些操作时是很方便的,如下:
#!/bin/bash

echo "正在运行的脚本为:$0!!"
  • 如下是两种运行脚本的方法的运行结果:
    在这里插入图片描述
  • 上述存在一个潜在的问题。如果使用**./命令**来运行shell脚本,命令会和脚本名混在一起,出现在$0参数中,当传给$0变量的实际字符串不仅仅是脚本名,而是完整的脚本路径时, 变量$0就会使用整个路径,如下:
    在这里插入图片描述
  • 如果我们要编写一个根据脚本名来执行不同功能的脚本,就得做点额外工作。得把脚本的运行路径给剥离掉。另外,还要删除与脚本名混杂在一起的命令,幸好有个方便的小命令可以帮到我们。basename命令会返回不包含路径的脚本名,如下:
#!/bin/bash

name=$(basename $0)
echo "正在运行的脚本为:$name!!"

在这里插入图片描述

  • 现在我们就可以使用这种方法来编写基于脚本名称执行不同功能的脚本,如下:
#!/bin/bash

name=$(basename $0)
if [ $name = "add_num" ]
then
        total=$[ $1 + $2 ]
elif [ $name = "mult_num" ]
then
        total=$[ $1 * $2 ]
fi
echo "计算结果为:$total"
  • 将此脚本复制两份名字为:add_num与mult_num,如下:
    在这里插入图片描述
  • 测试结果如下:
    在这里插入图片描述
  • 上述脚本,会根据脚本的名称不同来执行不一样的计算逻辑!!

测试参数

  • 在shell脚本中使用命令行参数需要注意。如果脚本不加参数运行,可能会出现问题,如下:
    在这里插入图片描述
  • 当脚本认为参数变量中会有数据而实际上并没有时,脚本很有可能会产生错误消息。这种写脚本的方法并不可取。所以,我们在使用参数前一定要检查其中是否存在数据,如下:
#!/bin/bash
if [ -n "$1" ]
then
        echo "欢迎您,$1!!"
else
        echo "请输入您的用户名!!"
fi

在这里插入图片描述

  • 在本例中,我们使用了-n测试来检查命令行参数$1中是否有数据,后续我们会学习另一种检查命令行参数的方法

特殊参数变量

  • 除上述的参数外,在bash shell中还有些特殊变量,它们会记录命令行参数,如下介绍

参数统计

  • 如在上面所看到的,在脚本中使用命令行参数之前应该检查一下命令行参数。对于使用多个命令行参数的脚本来说,这有点麻烦,因此,我们可以统计命令行中一共输入了多少个参数,无需测试每个参数。bash shell为此提供了一个特殊变量
  • **特殊变量$#**包含脚本运行时携带的命令行参数的个数。可以在脚本中任何地方使用这个特殊变量,就跟普通变量一样,如下:
#!/bin/bash

echo "你一共输入了$#个参数!!"

在这里插入图片描述

  • 现在我们可以在使用参数之前测试参数的总数是否符合要求,如下:
#!/bin/bash
if [ $# -eq 2 ]
then
        total=$[ $1 + $2 ]
        echo "计算结果为:$total"
else
        echo "请输入正确的参数!!"
fi

在这里插入图片描述

  • if-then语句用-eq测试命令行参数数量。如果参数数量不对,会显示一条错误消息告知脚
    本的正确用法。
  • 除此之外,还可以使用这个变量简便的获取命令行中最后一个参数,完全不需要知道实际上到底用了多少个参数,$#变量是输入参数的总数,那么变量${$#}就表示最后一个命令行参数,我们实际操作一下,如下:
#!/bin/bash

echo "最后一个参数为:${$#}"

在这里插入图片描述

  • 显然,上述的结果是不符合要求的。它表明我们不能在花括号内使用美元符。必须将美元符换成感叹号(!)。虽然奇怪,但确实有用,如下:

#!/bin/bash
var1=$#

echo "最后一个参数为:$var1"
echo "最后一个参数为:${!#}"

在这里插入图片描述

  • 在上述的脚本中将$#变量的值赋给了变量var1,然后也按特殊命令行参数变量的格式使用了该变量。两种方法都没问题。重要的是要注意,当命令行上没有任何参数时,$#的值为0,var1变量的值也一样,但${!#}变量会返回命令行用到的脚本名

获取所有参数

  • 有时候我们需要获取命令行上提供的所有参数。这时候就不需要先用$#变量来判断命令行上有多少参数,然后再进行遍历,你可以使用下述的一组其他的特殊变量来解决这个问题
  • $*和$@变量可以用来获取所有的参数。这两个变量都能够在单个变量中存储所有的命令行参数,如下介绍:
  • $*变量:
    • $*变量会将命令行上提供的所有参数当作一个单词保存。这个单词包含了命令行中出现的每一个参数值。基本上$*变量会将这些参数视为一个整体,而不是多个个体
  • $@变量:
    • $@变量会将命令行上提供的所有参数当作同一字符串中的多个独立的单词。这样
      你就能够遍历所有的参数值,得到每个参数。可以使用for命令循环,如下举例:
#!/bin/bash
echo
echo "\$* 获取的所有参数值为:$*"
echo
echo "\$@ 获取的所有参数值为:$@"

在这里插入图片描述

  • 从上述的例子中,表面上看,两个变量产生的是同样的输出,都显示出了所有命令行参数,但是其实本质上是不一样的,如下:
#!/bin/bash

count=1

for val in "$*"
do
        echo "\$*变量 #$count = $val"
        count=$[ $count + 1 ]
done
echo "----------------------------"
count=1
for var in "$@"
do
        echo "\$@变量 #$count = $var"
        count=$[ $count + 1 ]
done

在这里插入图片描述

  • 通过使用for命令遍历这两个特殊变量,可以看到它们是如何不同地处理命令行参数的。$*变量会将所有参数当成单个参数,而$@变量会单独处理每个参数

移动变量

  • bash shell还提供了一个工具命令shift。bash shell的shift命令能够用来操作命令行参数。跟字面上的意思一样,shift命令会根据它们的相对位置来移动命令行参数
  • 在使用shift命令时,默认情况下它会将每个参数变量向左移动一个位置。即为变量$3的值会移到$2中,变量$2的值会移到$1中,而变量$1的值则会被删除(注意,变量$0的值,也就是程序名,不会改变
  • 这是遍历命令行参数的另一种方法,尤其是在你不知道到底有多少参数时。你可以只操作第一个参数,移动参数,然后继续操作第一个参数,非常方便,如下:
#!/bin/bash

count=1
while [ -n "$1" ]
do
        echo "参数为:#$count = $1"
        count=$[ $count + 1]
        shift
done

在这里插入图片描述

  • 脚本通过测试第一个参数值是否存在执行了一个while循环。当第一个参数不存在,循环结束。测试完第一个参数后,shift命令会将所有参数的位置向左移动一个位置
  • 注意:使用shift命令的时候要小心。如果某个参数被移出,它的值就被丢弃了,无法再恢复
  • 另外,还可以一次性移动多个位置,只需要给shift命令提供一个数字类型参数,指明要移动的位置数即可,如下:
#!/bin/bash

echo
echo "初始参数为:$*"
echo "移动之前的第一个参数:$1"
shift 3
echo "移动之后的第一个参数:$1"

在这里插入图片描述

处理选项

  • 我们在使用命令时应该就见过了一些同时提供了参数和选项的bash命令,如 ls -l l就是选项。选项是跟在单破折线后面的单个字母,它能改变命令的行为。下面会介绍在脚本中处理选项的方法,如下介绍

查找选项

  • 表面上看,命令行选项也没什么特殊的。在命令行上,它们紧跟在脚本名之后,就跟命令行参数一样。实际上,我们可以像处理命令行参数一样处理命令行选项。

处理简单选项

  • 我们在上面已经学习了如何使用shift命令来依次处理脚本程序携带的命令行参数。也可以用同样的方法来处理命令行选项,在提取每个单独参数时,用case语句来判断某个参数是否为选项,如下:
#!/bin/bash

while [ -n "$1" ]
do
        case "$1" in
                -a) echo "-a参数存在"  ;;
                -b) echo "-b参数存在"  ;;
                -c) echo "-c参数存在"  ;;
                *) echo "$1参数不存在"  ;;
        esac
        shift
done

在这里插入图片描述

  • case语句会检查每个参数是不是有效选项。如果是的话,就运行对应case语句中的命令。不管选项按什么顺序出现在命令行上,这种方法都适用,case语句在命令行参数中找到一个选项,就处理一个选项。如果命令行上还提供了其他参数,我们可以在case语句的通用情况处理部分中处理

分离选项和参数

  • 我们还会在shell脚本中碰到同时使用选项和参数的情况。Linux中处理这个问题的标准方式是用特殊字符来将二者分开,该字符会告诉脚本何时选项结束以及普通参数何时开始
  • 对Linux来说,这个特殊字符是双破折线(--)。shell会用双破折线来表明选项列表结束。在双破折线之后,脚本就可以放心地将剩下的命令行参数当作参数,而不是选项来处理了。要检查双破折线,只要在case语句中加一项即可,如下:

#!/bin/bash

while [ -n "$1" ]
do
        case "$1" in
                -a) echo "-a选项存在"  ;;
                -b) echo "-b选项存在"  ;;
                -c) echo "-c选项存在"  ;;
                --) shift
                    break ;;
                *) echo "$1选项不存在"  ;;
        esac
        shift
done

count=1
for var in $@
do
        echo "参数为:#$count:$var"
        count=$[ $count + 1 ]
done

在这里插入图片描述

  • 当shell脚本遇到双破折线时,它会停止处理选项,并将剩下的参数都当作命令行参数

处理带值的选项

  • 有些选项会带上一个额外的参数值。在这种情况下,命令行看起来像下面这样:
./test.sh -a wy -b -c -d wwy
  • 当命令行选项要求额外的参数时,shell脚本必须能检测到并正确处理,如下:
#!/bin/bash

while [ -n "$1" ]
do
        case "$1" in
                -a) echo "-a选项存在"  ;;
                -b) var1="$2"
                    echo "-b选项存在,且参数为$var1"
                    shift ;;
                -c) echo "-c选项存在"  ;;
                --) shift
                    break ;;
                *) echo "$1选项不存在"  ;;
        esac
        shift
done

count=1
for var in $@
do
        echo "参数为:#$count:$var"
        count=$[ $count + 1 ]
done

在这里插入图片描述

  • 在上述例子中,case语句定义了三个它要处理的选项。-b选项还需要一个额外的参数值。由于要处理的参数是$1,额外的参数值就应该位于$2(因为所有的参数在处理完之后都会被移出)。只要将参数值从$2变量中提取出来就可以。当然,因为这个选项占用了两个参数位,所以你还需要使用shift命令多移动一个位置
  • 使用上述的基本特性,整个shell脚本过程就能正常工作,不管按什么顺序放置选项(但要记住包含每个选项相应的选项参数),如下:
    在这里插入图片描述
  • 现在我们的shell脚本中已经有了处理命令行选项的基本能力,但还有一些限制。比如,如果你想将多个选项放进一个参数中时,它就会出现问题,如下:
    在这里插入图片描述
  • 在Linux中,合并选项是一个很常见的用法,而且如果脚本想要对用户使用更加方便友好,也要给用户提供这种特性,下述会介绍处理方法

getopt 命令

  • getopt命令是一个在处理命令行选项和参数时非常方便的工具。它能够识别命令行参数,从而使脚本更加方便的处理命令行选项和参数

命令格式

  • getopt命令可以接受一系列任意形式的命令行选项和参数,并自动将它们转换成适当的格式。命令格式如下:
getopt optstring parameters
  • optstring是这个过程的关键所在。它定义了命令行有效的选项字母,还定义了哪些选项字母需要参数值,首先,在optstring中列出你要在脚本中用到的每个命令行选项字母。然后,在每个需要参数值的选项字母后加一个冒号。getopt命令会基于你定义的optstring解析提供的参数,如下简单举例:
getopt ab:cd -a -b wy -cd ww yy

在这里插入图片描述

  • optstring定义了四个有效选项字母:a、b、c和d,冒号(:)被放在了字母b后面,因为b选项需要一个参数值。当getopt命令运行时,它会检查提供的参数列表(-a -b wy -cd ww yy),并基于提供的optstring进行解析。注意,它会自动将-cd选项分成两个单独的选项,并插入双破折线来分隔行中的额外参数,如果指定了一个不在optstring中的选项,默认情况下,getopt命令会产生一条错误消息,如下:
getopt ab:cd -a -b wy -cd ww yy -e

在这里插入图片描述

  • 如果想要忽略这条错误消息,可以在命令后加-q选项,如下:
    在这里插入图片描述
  • 注意:getopt命令选项(-q)必须出现在optstring之前

在脚本中使用getopt

  • 可以在脚本中使用getopt来格式化脚本所携带的任何命令行选项或参数,但用起来略微复杂。方法是用getopt命令生成的格式化后的版本,使用set命令来替换已有的命令行选项和参数,set命令能够处理shell中的各种变量,set命令的选项之一是双破折线(--),它会将命令行参数替换成set命令的命令行值
  • 该方法会将原始脚本的命令行参数传给getopt命令,之后再将getopt命令的输出传给set命令,用getopt格式化后的命令行参数来替换原始的命令行参数,如下格式:
set -- $(getopt -q ab:cd "$@")
  • 原始的命令行参数变量的值会被getopt命令的输出替换,而getopt已经为我们格式化
    好了命令行参数,如下:
#!/bin/bash

set -- $(getopt -q ab:cd "$@")

while [ -n "$1" ]
do
        case "$1" in
                -a) echo "-a选项存在"  ;;
                -b) var1="$2"
                    echo "-b选项存在,且参数为$var1"
                    shift ;;
                -c) echo "-c选项存在"  ;;
                --) shift
                    break ;;
                *) echo "$1选项不存在"  ;;
        esac
        shift
done

count=1
for var in $@
do
        echo "参数为:#$count:$var"
        count=$[ $count + 1 ]
done

在这里插入图片描述

  • 上述运行结果显示,已经达到我们预期的结果,但是,在getopt命令中仍然隐藏着一个小问题,如下:
    在这里插入图片描述
  • getopt命令并不擅长处理带空格和引号的参数值。它会将空格当作参数分隔符,而不是根据双引号将二者当作一个参数,如下介绍解决方法

getopts命令

  • 与getopt不同,getopt将命令行上选项和参数处理后只生成一个输出,而getopts命令能够和已有的shell参数变量配合默契。每次调用它时,它一次只处理命令行上检测到的一个参数。处理完所有的参数后,它会退出并返回一个大于0的退出状态码,命令格式如下:
getopts optstring variable
  • optstring值类似于getopt命令中的那个。有效的选项字母都会列在optstring中,如果选项字母要求有个参数值,就加一个冒号。要去掉错误消息的话,可以在optstring之前加一个冒号。getopts命令将当前参数保存在命令行中定义的variable中
  • getopts命令会用到两个环境变量。如果选项需要跟一个参数值,OPTARG环境变量就会保存这个参数值。OPTIND环境变量保存了参数列表中getopts正在处理的参数位置。这样就能在处理完选项之后继续处理其他命令行参数,如下:
#!/bin/bash
while getopts :ab:c opt
do
        case "$opt" in
                a) echo "选项-a存在!!";;
                b) echo "选项-b存在,且参数值为$OPTARG!!";;
                c) echo "选项-c存在!!";;
                *) echo "选项$opt不存在!!";;
        esac
done

在这里插入图片描述

  • while语句定义了getopts命令,指明了要查找哪些命令行选项,以及每次迭代中存储它们的变量名(opt),注意,在本例中case语句的用法有些不同。getopts命令解析命令行选项会移除开头的单破折线,所以在case定义中不用单破折线
  • getopts命令有几个好用的功能,可以在参数值中包含空格,如下:
    在这里插入图片描述
  • 还可以将选项字母和参数值放在一起使用,而不用加空格,如下:
    在这里插入图片描述
  • getopts命令能够从-b选项中正确解析出参数wyyy值。除此之外,getopts还能够将命令行上找到的所有未定义的选项统一输出成问号,如下:
    在这里插入图片描述
  • optstring中未定义的选项字母会以问号形式发送给代码,getopts命令知道何时停止处理选项,并将参数留给你处理
  • 在getopts处理每个选项时,它会将OPTIND环境变量值增一。在getopts完成处理时,你可以使用shift命令和OPTIND值来移动参数,如下:
#!/bin/bash

while getopts :ab:cd opt
do
        case "$opt" in
                a) echo "参数-a存在!!" ;;
                b) echo "参数-b存在!!,且参数值为$OPTARG" ;;
                c) echo "参数-c存在!!" ;;
                d) echo "参数-d存在!!" ;;
                *) echo "参数$opt不存在!!" ;;
        esac
done
echo "---------------------------"
shift $[ $OPTIND - 1 ]
count=1
for var in "$@"
do
        echo "第$count参数值为$var!!"
        count=$[ $count + 1 ]
done

在这里插入图片描述

脚本选项标准化

  • 在创建shell脚本时,我们完全可以决定用哪些字母选项以及它们的用法,但有些字母选项在Linux世界里已经拥有了某种程度的标准含义。如果你能在shell脚本中支持这些选项,会使得你的脚本更加方便,如下表所示:
选 项描 述
-a显示所有对象
-c生成一个计数
-d指定一个目录
-e扩展一个对象
-f指定读入数据的文件
-h显示命令的帮助信息
-i忽略文本大小写
-l产生输出的长格式版本
-n使用非交互模式(批处理)
-o将所有输出重定向到的指定的输出文件
-q以安静模式运行
-r递归地处理目录和文件
-s以安静模式运行
-v生成详细输出
-x排除某个对象
-y对所有问题回答yes

获取用户的输入

  • 虽然命令行选项和参数是从脚本用户处获得输入的一种方式,但有时脚本的交互性还需要更强一些。比如我们想要在脚本运行时获取用户对某个问题的答案,因此bash shell提供了read命令

基本的读取

  • read命令会从标准输入(键盘)或另一个文件描述符中接受输入。在收到输入后,read命令会将数据放进一个变量,如下:
#!/bin/bash

echo -n  "请输入用户名:"
read name
echo "您好$name,欢迎登陆!!"

在这里插入图片描述

  • 注意,生成提示的echo命令使用了-n选项。该选项不会在字符串末尾输出换行符,允许脚本用户紧跟其后输入数据,而不是下一行。这让脚本看起来更像表单
  • 但是实际上,read命令包含了-p选项,允许你直接在read命令行指定提示符,如下:
#!/bin/bash
read -p "请入输入一个数字:" num
pf_num=$[ $num * $num ]
echo "它的平方为:$pf_num!!"

在这里插入图片描述

  • read命令会将提示符后输入的所有数据分配给单个变量,要么指定多个变量。输入的每个数据值都会分配给变量列表中的下一个变量。如果变量数量不够,剩下的数据就全部分配给最后一个变量
  • 也可以在read命令行中不指定变量。如果是这样,read命令会将它收到的任何数据都放进特殊环境变量REPLY中,如下:
#!/bin/bash
read -p "请入用户名:"
echo "--------------"
echo "欢迎您$REPLY,登录!!"

在这里插入图片描述

  • REPLY环境变量会保存输入的所有数据,可以在shell脚本中像其他变量一样使用

超时

  • 使用read命令时要注意。脚本可能会一直在等用户的输入。如果不管是否有数据输入,脚本都必须继续执行,你可以用**-t选项**来指定一个计时器。-t选项指定了read命令等待输入的秒数。当计时器过期后,read命令会返回一个非零退出状态码,如下:
#!/bin/bash
if read -t 3 -p "请入用户名:" name
then
        echo "欢迎您$name,登录!!"
else
        echo
        echo "等待超时,请重试!!"
fi

在这里插入图片描述

  • 如果计时器过期,read命令会以非零退出状态码退出,可以使用如if-then语句或while循环这种标准的结构化语句来处理所发生的具体情况。在上例中,计时器过期时,if语句不成立,shell会执行else部分的命令
  • 也可以不对输入过程计时,而是让read命令来统计输入的字符数。当输入的字符达到预设的字符数时,就自动退出,将输入的数据赋给变量,如下:
#!/bin/bash
read -n1 -p "你是否要继续 [Y/N]" answer
case $answer in
        Y | y)echo
                echo "继续执行!!";;
        N | n)echo
                echo "再见!!"
                exit;;
esac
echo "执行完毕!!"

在这里插入图片描述

  • 上例中将**-n选项和值1**一起使用,告诉read命令在接受单个字符后退出。只要按下单个字符后,read命令就会接受输入并将它传给变量,无需按回车键

隐藏式读取

  • 有时你需要从脚本用户处获取输入,但是不需要在屏幕上显示输入信息。其中典型的例子就是输入的密码,但除此之外还有很多其他需要隐藏的数据类型
  • -s选项可以避免在read命令中输入的数据出现在显示器上(实际上,数据会被显示,只是read命令会将文本颜色设成跟背景色一样),如下:
#!/bin/bash
read -s -p "请输入您的密码:" password
echo
echo "您的密码是:$password"

在这里插入图片描述

文件中读取

  • 也可以用read命令来读取Linux系统上文件里保存的数据。每次调用read命令,它都会从文件中读取一行文本。当文件中再没有内容时,read命令会退出并返回非零退出状态码
  • 其中最主要的部分就是将文件中的数据传给read命令,最常见的方法是对文件使用cat命令,将结果通过管道直接传给含有read命令的while命令,如下:
#!/bin/bash
count=1
cat name | while read line
do
        echo "第$count行为:$line"
        count=$[ $count + 1 ]
done
echo "处理结束!!!"

在这里插入图片描述

  • while循环会持续通过read命令处理文件中的行,直到read命令以非零退出状态码退出

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

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

相关文章

Linux命令·ifconfig

许多windows非常熟悉ipconfig命令行工具&#xff0c;它被用来获取网络接口配置信息并对此进行修改。Linux系统拥有一个类似的工具&#xff0c;也就是ifconfig(interfaces config)。通常需要以root身份登录或使用sudo以便在Linux机器上使用ifconfig工具。依赖于ifconfig命令中使…

OpenFeign#1 - FeignClient 是如何注册的?

文章目录EnableFeignClientsFeignClientsRegistrarregisterDefaultConfigurationregisterFeignClientsFeignClientFeignClientFactoryBeanFeignContextfeign(FeignContext)EnableFeignClients 该注解会导致 FeignClientsRegistrar 的注入. Retention(RetentionPolicy.RUNTIME…

Redis AOF

一、Redis AOF 1.简介 目前&#xff0c;redis的持久化主要应用AOF(Append Only File)和RDB两大机制。AOF以日志的形式来记录每个写操作(增量保存),将redis执行过的所有写指令全部记录下来(读操作不记录)。只许追加文件&#xff0c;但不可以改写文件。redis启动之初会读取该文…

自动化测试学习(七)-正则表达式,你真的会用吗?

目录 一、正则表达式在python中如何使用 二、用正则表达式匹配更多模式 三、常用字符分类的缩写代码 总结 所谓正则表达式&#xff08;regex&#xff09;&#xff0c;就是一种模式匹配&#xff0c;学会用正则匹配&#xff0c;就可以达到事半功倍的效果。 一、正则表达式在…

工程管理系统软件 自主研发,工程行业适用

Java版工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离 功能清单如下&#xff1a; 首页 工作台&#xff1a;待办工作、消息通知、预警信息&#xff0c;点击可进入相应的列表 项目进度图表&#xff1a;选择&#xff08;总体或单个&#xff09;项目显示…

在 Web3 里如何寻找靠谱的创新路径——Solv V3 阶段性复盘(上)

作者&#xff1a;Solv 核心团队Solv V3 是 3 月 21 日发布的&#xff0c;到这周一整整三个星期。三周时间产生的实际交易额超过 6,000 万美元&#xff0c;预计在本月内能够破亿。而且从我们手上的 pipeline 来看&#xff0c;这个增长的势头还将持续下去。在几个月内&#xff0c…

「Long HK, Long Crypto」主题酒会在香港圆满举行!Web3er齐聚一堂共叙行业发展

「2023 香港 Web3 嘉年华」是香港有史以来规模最大的加密货币活动之一&#xff0c;邀请了300多位行业领袖、区块链项目创始人、投资人、监管机构代表、专家学者&#xff0c;为每一位参与者带来前沿的 Web3 技术&#xff0c;共同探讨 Web3 未来发展的关键问题。 Web3相关的各大…

OpenCV实战(19)——特征描述符

OpenCV实战&#xff08;19&#xff09;——特征描述符0. 前言1. 特征描述符2. 提升匹配集质量2.1 交叉检查匹配2.2 比率测试2.3 距离阈值3. 完整代码小结系列链接0. 前言 SURF 和 SIFT 关键点检测算法为每个检测到的特征计算位置、方向和比例&#xff0c;比例因子信息可用于定…

RestClient查询文档

文章目录1、RestClient查询文档----快速入门2、查询文档--match、term、range、bool3、查询文档-排序和分页4、高亮1、RestClient查询文档----快速入门 基本步骤 1.先创建SearchRequest对象&#xff0c;调用source方法&#xff08;DSL&#xff09;——>相当于红框内的大jso…

最前端|什么是低代码?与传统开发的区别是什么?

目录一、低代码介绍二、背景趋势三、低代码与传统代码开发&#xff08;一&#xff09;低代码能否替代传统开发低代码页面传统开发页面&#xff08;二&#xff09;相同业务不同方式对比1.低代码开发&#xff08;1&#xff09;优点&#xff08;2&#xff09;缺点2.传统代码开发&a…

实现一个登录功能方案设计2

需求MySQL表实现方案index页面home页面需求 实现一个登录功能 实现的功能 注册(邮箱注册)登录(邮箱密码)重置密码查看操作记录(登录, 注册, 重置密码, 登出. 都算操作)登出在第一版的基础上进行优化:\ 优化点: 存操作信息请求的post使用中间件进行储存操作信息.避免重复代码 因…

【面试】如何设计SaaS产品的数据权限?

文章目录前言数据权限是什么&#xff1f;设计原则整体方案RBAC模型怎么控制数据权限&#xff1f;1. 数据范围权限控制2. 业务对象操作权限控制3. 业务对象字段权限控制总结前言 一套系统的权限可以分为两类&#xff0c;数据权限和功能权限&#xff0c;今天我们从以下几个点&am…

阿里云服务器安装宝塔面板搭建网站全流程(一步步详解)

阿里云服务器安装宝塔面板教程&#xff0c;云服务器吧以阿里云Linux系统云服务器安装宝塔Linux面板为例&#xff0c;先配置云服务器安全组开放宝塔所需端口8888、888、80、443、20和21端口&#xff0c;然后执行安装宝塔面板命令脚本&#xff0c;最后登录宝塔后台安装LNMP&#…

UML 简易使用教程

最近刚好有空&#xff0c;遂决定对应 UML 常用的一些图进行整理&#xff0c;供自己以及需要的人查阅。 UML 分为静态模型与动态模型。静态模型描述一个系统的静态特征&#xff0c;固定的框架结构。包括用例图、类图、对象图、组件图、部署图&#xff1b;动态模型包括时序图、协…

TensorFlow 智能移动项目:11~12

原文&#xff1a;Intelligent mobile projects with TensorFlow 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 本文来自【ApacheCN 深度学习 译文集】&#xff0c;采用译后编辑&#xff08;MTPE&#xff09;流程来尽可能提升效率。 不要担心自己的形象&#xff0c;只…

Flutter 第一个界面

第一个页面 app首页 入口函数 一个Flutter工程的入口函数与Dart命令行工程一样是main&#xff0c;不同的是在Flutter中执行runApp(ArticleApp()) 就能够在手机屏幕上展示这个Widget。 import package:flutter/material.dart; void main() > runApp(new ArticleApp()); Ar…

OpenAI不能访问有什么方法解救呢?试试这方法吧

最近发现国内不挂代理是不能访问到openAI的接口的&#xff0c;为了解决这个问题&#xff0c;我一直在github上需在解决方案&#xff0c;今天终于被我找到一个大神开源了一个解决方案。下面就来看看如何做吧。 整个项目的代码很简单只有几行代码&#xff1a; {"rewrites&q…

几种在Python中List添加、删除元素的方法

嗨害大家好鸭&#xff01;我是爱摸鱼的芝士❤ 一、python中List添加元素的几种方法 List 是 Python 中常用的数据类型&#xff0c; 它一个有序集合&#xff0c; 即其中的元素始终保持着初始时的定义的顺序 &#xff08;除非你对它们进行排序或其他修改操作&#xff09;。 …

进程互斥的实现方式

1.进程互斥的软件实现方法 1.单标志法 算法思想&#xff1a;两个进程在访问完临界区后会把使用临界区的权限转让给另一个进程&#xff0c;也就是说每个进程进入临界区的权限只能被另一个进程赋予 局限性 2.双标志先检查法 算法思想&#xff1a;设置一个布尔数组flag[]&#xff…

python 笔记:PyTrack(将GPS数据和OpenStreetMap数据进行整合)【官网例子解读】

论文笔记&#xff1a;PyTrack: A Map-Matching-Based Python Toolbox for Vehicle Trajectory Reconstruction_UQI-LIUWJ的博客-CSDN博客4 0 包的安装 官网的两种方式我都试过&#xff0c;装是能装成功&#xff0c;但是python import PyTrack包的时候还是显示找不到Pytrack …