bash脚本调试方法

2023-11-02

本文全面系统地介绍了shell脚本调试技术,包括使用echo, tee, trap等命令输出关键信息,跟踪变量的值,在脚本中植入调试钩子,使用“-n”选项进行shell脚本的语法检查, 使用“-x”选项实现shell脚本逐条语句的跟踪,巧妙地利用shell的内置变量增强“-x”选项的输出信息等。
    
一. 前言
shell编程在unix/linux世界中使用得非常广泛,熟练掌握shell编程也是成为一名优秀的unix/linux开发者和系统管理员的必经之 路。脚本调试的主要工作就是发现引发脚本错误的原因以及在脚本源代码中定位发生错误的行,常用的手段包括分析输出的错误信息,通过在脚本中加入调试语句, 输出调试信息来辅助诊断错误,利用调试工具等。但与其它高级语言相比,shell解释器缺乏相应的调试机制和调试工具的支持,其输出的错误信息又往往很不 明确,初学者在调试脚本时,除了知道用echo语句输出一些信息外,别无它法,而仅仅依赖于大量的加入echo语句来诊断错误,确实令人不胜其繁,故常见 初学者抱怨shell脚本太难调试了。本文将系统地介绍一些重要的shell脚本调试技术,希望能对shell的初学者有所裨益。

本文的目标读者是unix/linux环境下的开发人员,测试人员和系统管理员,要求读者具有基本的shell编程知识。本文所使用范例在 Bash3.1+Redhat Enterprise Server 4.0下测试通过,但所述调试技巧应也同样适用于其它shell。
    
二. 在shell脚本中输出调试信息
通过在程序中加入调试语句把一些关键地方或出错的地方的相关信息显示出来是最常见的调试手段。Shell程序员通常使用echo(ksh程序员常使用 print)语句输出信息,但仅仅依赖echo语句的输出跟踪信息很麻烦,调试阶段在脚本中加入的大量的echo语句在产品交付时还得再费力一一删除。针 对这个问题,本节主要介绍一些如何方便有效的输出调试信息的方法。

1. 使用trap命令
trap命令用于捕获指定的信号并执行预定义的命令。
其基本的语法是:
trap 'command' signal
其中signal是要捕获的信号,command是捕获到指定的信号之后,所要执行的命令。可以用kill –l命令看到系统中全部可用的信号名,捕获信号后所执行的命令可以是任何一条或多条合法的shell语句,也可以是一个函数名。
shell脚本在执行时,会产生三个所谓的“伪信号”,(之所以称之为“伪信号”是因为这三个信号是由shell产生的,而其它的信号是由操作系统产生 的),通过使用trap命令捕获这三个“伪信号”并输出相关信息对调试非常有帮助。

shell伪信号
信号名 何时产生
EXIT 从一个函数中退出或整个脚本执行完毕
ERR 当一条命令返回非零状态时(代表命令执行不成功)
DEBUG 脚本中每一条命令执行之前

通过捕获EXIT信号,我们可以在shell脚本中止执行或从函数中退出时,输出某些想要跟踪的变量的值,并由此来判断脚本的执行状态以及出错原因,其使 用方法是:
trap 'command' EXIT 或 trap 'command' 0
通过捕获ERR信号,我们可以方便的追踪执行不成功的命令或函数,并输出相关的调试信息,以下是一个捕获ERR信号的示例程序,其中的$LINENO是一 个shell的内置变量,代表shell脚本的当前行号。
$ cat -n exp1.sh
     1 ERRTRAP()
     2 {
     3    echo "[LINE:$1] Error: Command or function exited with status $?"
     4 }
     5 foo()
     6 {
     7    return 1;
     8 }
     9 trap 'ERRTRAP $LINENO' ERR
    10 abc
    11 foo
    
其输出结果如下:
$ sh exp1.sh
exp1.sh: line 10: abc: command not found
[LINE:10] Error: Command or function exited with status 127
[LINE:11] Error: Command or function exited with status 1

在调试过程中,为了跟踪某些变量的值,我们常常需要在shell脚本的许多地方插入相同的echo语句来打印相关变量的值,这种做法显得烦琐而笨拙。而通 过捕获DEBUG信号,我们只需要一条trap语句就可以完成对相关变量的全程跟踪。
以下是一个通过捕获DEBUG信号来跟踪变量的示例程序:
$ cat –n exp2.sh
     1 #!/bin/bash
     2 trap 'echo “before execute line:$LINENO, a=$a,b=$b,c=$c”' DEBUG
     3 a=1
     4 if [ "$a" -eq 1 ]
     5 then
     6     b=2
     7 else
     8     b=1
     9 fi
    10 c=3
    11 echo "end"

其输出结果如下:
$ sh exp2.sh
before execute line:3, a=,b=,c=
before execute line:4, a=1,b=,c=
before execute line:6, a=1,b=,c=
before execute line:10, a=1,b=2,c=
before execute line:11, a=1,b=2,c=3
end

从运行结果中可以清晰的看到每执行一条命令之后,相关变量的值的变化。同时,从运行结果中打印出来的行号来分析,可以看到整个脚本的执行轨迹,能够判断出 哪些条件分支执行了,哪些条件分支没有执行。

2. 使用tee命令
在shell脚本中管道以及输入输出重定向使用得非常多,在管道的作用下,一些命令的执行结果直接成为了下一条命令的输入。如果我们发现由管道连接起来的 一批命令的执行结果并非如预期的那样,就需要逐步检查各条命令的执行结果来判断问题出在哪儿,但因为使用了管道,这些中间结果并不会显示在屏幕上,给调试 带来了困难,此时我们就可以借助于tee命令了。

tee命令会从标准输入读取数据,将其内容输出到标准输出设备,同时又可将内容保存成文件。例如有如下的脚本片段,其作用是获取本机的ip地址:
ipaddr=`/sbin/ifconfig | grep 'inet addr:' | grep -v '127.0.0.1'
| cut -d : -f3 | awk '{print $1}'`
#注意=号后面的整句是用反引号(数字1键的左边那个键)括起来的。
echo $ipaddr

运行这个脚本,实际输出的却不是本机的ip地址,而是广播地址,这时我们可以借助tee命令,输出某些中间结果,将上述脚本片段修改为:
ipaddr=`/sbin/ifconfig | grep 'inet addr:' | grep -v '127.0.0.1'
| tee temp.txt | cut -d : -f3 | awk '{print $1}'`
echo $ipaddr

之后,将这段脚本再执行一遍,然后查看temp.txt文件的内容:
$ cat temp.txt
inet addr:192.168.0.1 Bcast:192.168.0.255 Mask:255.255.255.0

我们可以发现中间结果的第二列(列之间以:号分隔)才包含了IP地址,而在上面的脚本中使用cut命令截取了第三列,故我们只需将脚本中的cut -d : -f3改为cut -d : -f2即可得到正确的结果。
具体到上述的script例子,我们也许并不需要tee命令的帮助,比如我们可以分段执行由管道连接起来的各条命令并查看各命令的输出结果来诊断错误,但 在一些复杂的shell脚本中,这些由管道连接起来的命令可能又依赖于脚本中定义的一些其它变量,这时我们想要在提示符下来分段运行各条命令就会非常麻烦 了,简单地在管道之间插入一条tee命令来查看中间结果会更方便一些。

3. 使用"调试钩子"
在C语言程序中,我们经常使用DEBUG宏来控制是否要输出调试信息,在shell脚本中我们同样可以使用这样的机制,如下列代码所示:
if [ “$DEBUG” = “true” ]; then
echo “debugging” #此处可以输出调试信息
fi

这样的代码块通常称之为“调试钩子”或“调试块”。在调试钩子内部可以输出任何您想输出的调试信息,使用调试钩子的好处是它是可以通过DEBUG变量来控 制的,在脚本的开发调试阶段,可以先执行export DEBUG=true命令打开调试钩子,使其输出调试信息,而在把脚本交付使用时,也无需再费事把脚本中的调试语句一一删除。
如果在每一处需要输出调试信息的地方均使用if语句来判断DEBUG变量的值,还是显得比较繁琐,通过定义一个DEBUG函数可以使植入调试钩子的过程更 简洁方便,如下面代码所示:
$ cat –n exp3.sh
     1 DEBUG()
     2 {
     3 if [ "$DEBUG" = "true" ]; then
     4      $@  
     5 fi
     6 }
     7 a=1
     8 DEBUG echo "a=$a"
     9 if [ "$a" -eq 1 ]
    10 then
    11       b=2
    12 else
    13       b=1
    14 fi
    15 DEBUG echo "b=$b"
    16 c=3
    17 DEBUG echo "c=$c"
在上面所示的DEBUG函数中,会执行任何传给它的命令,并且这个执行过程是可以通过DEBUG变量的值来控制的,我们可以把所有跟调试有关的命令都作为 DEBUG函数的参数来调用,非常的方便。
    
三. 使用shell的执行选项
上一节所述的调试手段是通过修改shell脚本的源代码,令其输出相关的调试信息来定位错误的,那有没有不修改源代码来调试shell脚本的方法呢?答案 就是使用shell的执行选项,本节将介绍一些常用选项的用法:

-n 只读取shell脚本,但不实际执行
-x 进入跟踪方式,显示所执行的每一条命令
-c "string" 从strings中读取命令

“-n”可用于测试shell脚本是否存在语法错误,但不会实际执行命令。在shell脚本编写完成之后,实际执行之前,首先使用“-n”选项来测试脚本 是否存在语法错误是一个很好的习惯。因为某些shell脚本在执行时会对系统环境产生影响,比如生成或移动文件等,如果在实际执行才发现语法错误,您不得 不手工做一些系统环境的恢复工作才能继续测试这个脚本。
“-c”选项使shell解释器从一个字符串中而不是从一个文件中读取并执行shell命令。当需要临时测试一小段脚本的执行结果时,可以使用这个选项, 如下所示:
sh -c 'a=1;b=2;let c=$a+$b;echo "c=$c"'
"-x"选项可用来跟踪脚本的执行,是调试shell脚本的强有力工具。“-x”选项使shell在执行脚本的过程中把它实际执行的每一个命令行显示出 来,并且在行首显示一个"+"号。 "+"号后面显示的是经过了变量替换之后的命令行的内容,有助于分析实际执行的是什么命令。 “-x”选项使用起来简单方便,可以轻松对付大多数的shell调试任务,应把其当作首选的调试手段。

如果把本文前面所述的trap ‘command’ DEBUG机制与“-x”选项结合起来,我们就可以既输出实际执行的每一条命令,又逐行跟踪相关变量的值,对调试相当有帮助。
仍以前面所述的exp2.sh为例,现在加上“-x”选项来执行它:
$ sh –x exp2.sh
+ trap 'echo "before execute line:$LINENO, a=$a,b=$b,c=$c"' DEBUG
++ echo 'before execute line:3, a=,b=,c='
before execute line:3, a=,b=,c=
+ a=1
++ echo 'before execute line:4, a=1,b=,c='
before execute line:4, a=1,b=,c=
+ '[' 1 -eq 1 ']'
++ echo 'before execute line:6, a=1,b=,c='
before execute line:6, a=1,b=,c=
+ b=2
++ echo 'before execute line:10, a=1,b=2,c='
before execute line:10, a=1,b=2,c=
+ c=3
++ echo 'before execute line:11, a=1,b=2,c=3'
before execute line:11, a=1,b=2,c=3
+ echo end
end

在上面的结果中,前面有“+”号的行是shell脚本实际执行的命令,前面有“++”号的行是执行trap机制中指定的命令,其它的行则是输出信息。
shell的执行选项除了可以在启动shell时指定外,亦可在脚本中用set命令来指定。 "set -参数"表示启用某选项,"set +参数"表示关闭某选项。有时候我们并不需要在启动时用"-x"选项来跟踪所有的命令行,这时我们可以在脚本中使用set命令,如以下脚本片段所示:
set -x    #启动"-x"选项
要跟踪的程序段
set +x     #关闭"-x"选项
set命令同样可以使用上一节中介绍的调试钩子—DEBUG函数来调用,这样可以避免脚本交付使用时删除这些调试语句的麻烦,如以下脚本片段所示:
DEBUG set -x    #启动"-x"选项
要跟踪的程序段
DEBUG set +x    #关闭"-x"选项
    
四. 对"-x"选项的增强
"-x"执行选项是目前最常用的跟踪和调试shell脚本的手段,但其输出的调试信息仅限于进行变量替换之后的每一条实际执行的命令以及行首的一个"+" 号提示符,居然连行号这样的重要信息都没有,对于复杂的shell脚本的调试来说,还是非常的不方便。幸运的是,我们可以巧妙地利用shell内置的一些 环境变量来增强"-x"选项的输出信息,下面先介绍几个shell内置的环境变量:

$LINENO
代表shell脚本的当前行号,类似于C语言中的内置宏__LINE__
$FUNCNAME
函数的名字,类似于C语言中的内置宏__func__,但宏__func__只能代表当前所在的函数名,而$FUNCNAME的功能更强大,它是一个数组 变量,其中包含了整个调用链上所有的函数的名字,故变量${FUNCNAME[0]}代表shell脚本当前正在执行的函数的名字,而变 量${FUNCNAME[1]}则代表调用函数${FUNCNAME[0]}的函数的名字,余者可以依此类推。
$PS4
主提示符变量$PS1和第二级提示符变量$PS2比较常见,但很少有人注意到第四级提示符变量$PS4的作用。我们知道使用“-x”执行选项将会显示 shell脚本中每一条实际执行过的命令,而$PS4的值将被显示在“-x”选项输出的每一条命令的前面。在Bash Shell中,缺省的$PS4的值是"+"号。(现在知道为什么使用"-x"选项时,输出的命令前面有一个"+"号了吧?)。

利用$PS4这一特性,通过使用一些内置变量来重定义$PS4的值,我们就可以增强"-x"选项的输出信息。例如先执行export PS4='+{$LINENO:${FUNCNAME[0]}} ', 然后再使用“-x”选项来执行脚本,就能在每一条实际执行的命令前面显示其行号以及所属的函数名。
以下是一个存在bug的shell脚本的示例,本文将用此脚本来示范如何用“-n”以及增强的“-x”执行选项来调试shell脚本。这个脚本中定义了一 个函数isRoot(),用于判断当前用户是不是root用户,如果不是,则中止脚本的执行
$ cat –n exp4.sh
     1 #!/bin/bash
     2 isRoot()
     3 {
     4          if [ "$UID" -ne 0 ]
     5                  return 1
     6          else
     7                  return 0
     8          fi
     9 }
    10 isRoot
    11 if ["$?" -ne 0 ]
    12 then
    13          echo "Must be root to run this script"
    14          exit 1
    15 else
    16          echo "welcome root user"
    17          #do something
    18 fi

首先执行sh –n exp4.sh来进行语法检查,输出如下:
$ sh –n exp4.sh
exp4.sh: line 6: syntax error near unexpected token `else'
exp4.sh: line 6: `      else'
发现了一个语法错误,通过仔细检查第6行前后的命令,我们发现是第4行的if语句缺少then关键字引起的(写惯了C程序的人很容易犯这个错误)。我们可 以把第4行修改为if [ "$UID" -ne 0 ]; then来修正这个错误。再次运行sh –n exp4.sh来进行语法检查,没有再报告错误。接下来就可以实际执行这个脚本了,执行结果如下:
$ sh exp4.sh
exp2.sh: line 11: [1: command not found
welcome root user

尽管脚本没有语法错误了,在执行时却又报告了错误。错误信息还非常奇怪“[1: command not found”。现在我们可以试试定制$PS4的值,并使用“-x”选项来跟踪:
$ export PS4='+{$LINENO:${FUNCNAME[0]}} '
$ sh –x exp4.sh
+{10:} isRoot
+{4:isRoot} '[' 503 -ne 0 ']'
+{5:isRoot} return 1
+{11:} '[1' -ne 0 ']'
exp4.sh: line 11: [1: command not found
+{16:} echo 'welcome root user'
welcome root user

从输出结果中,我们可以看到脚本实际被执行的语句,该语句的行号以及所属的函数名也被打印出来,从中可以清楚的分析出脚本的执行轨迹以及所调用的函数的内 部执行情况。由于执行时是第11行报错,这是一个if语句,我们对比分析一下同为if语句的第4行的跟踪结果:
+{4:isRoot} '[' 503 -ne 0 ']'
+{11:} '[1' -ne 0 ']'

可知由于第11行的[号后面缺少了一个空格,导致[号与紧挨它的变量$?的值1被shell解释器看作了一个整体,并试着把这个整体视为一个命令来执行, 故有“[1: command not found”这样的错误提示。只需在[号后面插入一个空格就一切正常了。
shell中还有其它一些对调试有帮助的内置变量,比如在Bash Shell中还有BASH_SOURCE, BASH_SUBSHELL等一批对调试有帮助的内置变量,您可以通过man sh或man bash来查看,然后根据您的调试目的,使用这些内置变量来定制$PS4,从而达到增强“-x”选项的输出信息的目的。
    
五. 总结
现在让我们来总结一下调试shell脚本的过程:
首先使用“-n”选项检查语法错误,然后使用“-x”选项跟踪脚本的执行,使用“-x”选项之前,别忘了先定制PS4变量的值来增强“-x”选项的输出信 息,至少应该令其输出行号信息(先执行export PS4='+[$LINENO]',更一劳永逸的办法是将这条语句加到您用户主目录的.bash_profile文件中去),这将使你的调试之旅更轻松。 也可以利用trap,调试钩子等手段输出关键调试信息,快速缩小排查错误的范围,并在脚本中使用“set -x”及“set +x”对某些代码块进行重点跟踪。这样多种手段齐下,相信您已经可以比较轻松地抓出您的shell脚本中的臭虫了。如果您的脚本足够复杂,还需要更强的调 试能力,可以使用shell调试器bashdb,这是一个类似于GDB的调试工具,可以完成对shell脚本的断点设置,单步执行,变量观察等许多功能, 使用bashdb对阅读和理解复杂的shell脚本也会大有裨益。关于bashdb的安装和使用,不属于本文范围,您可参阅http://bashdb.sourceforge.net/ 上 的文档并下载试用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

bash脚本调试方法 的相关文章

  • 在 bash 中添加(收集)退出代码

    我需要依赖于脚本中的几个单独的执行 并且不想将它们全部捆绑在一个丑陋的 if 语句中 我想使用退出代码 每次执行并添加它 最后 如果这个值超过阈值 我想执行一个命令 伪代码 ALLOWEDERROR 5 run something RESU
  • 如何使用 docker ENTRYPOINT 与 shell 脚本文件组合参数

    我编写 shell 脚本文件并将其与 docker ENTRYPOINT 一起使用 但是当我运行 docker image 时 由于入口点代码行 它只是停止而没有任何错误日志 我的 Dockerfile FROM ubuntu 16 04
  • awk 在循环中使用时不打印任何内容[重复]

    这个问题在这里已经有答案了 我有一堆使用 file 1 a 1 txt 格式的文件 如下所示 A 1 B 2 C 3 D 4 并使用以下命令添加包含每个文件名称的新列 awk print FILENAME NF t 0 file 1 a 1
  • bash 子 shell 中出现陷阱“kill 0”的分段错误

    我正在尝试编写一个并行构建多个 Dockerfile 的小脚本 但是如果我想取消该脚本 我也想杀死子进程 这样做的结果是segmentation fault 不知道为什么 为了澄清我正在杀死脚本 C trap kill 0 SIGINT S
  • linux下无法创建僵尸进程

    嗯 我有一个奇怪的问题 我无法在我的项目中创建僵尸进程 但我可以在其他文件中创建僵尸进程 有简单的说明 int main if fork 0 printf Some instructions n else sleep 10 wait 0 r
  • 如何从 LaTeX 执行 shell 脚本?

    我正在尝试在 LaTeX 中执行以下操作 documentclass article begin document execute usr local bin my shell script sh end document 想法是执行 us
  • 检查帐号是否为数字时出现语法错误

    if account nr 0 9 from account nr 0 9 这是为了检查帐号是否为数字 我收到语法错误 这个问题的早期版本缺少之间的空格if and 实际代码具有所需的空间 它显示以下错误消息 syntax error ac
  • 执行“minikube start”命令时出现问题

    malik malik minikube start minikube v1 12 0 on Ubuntu 18 04 Using the docker driver based on existing profile Starting c
  • Bash while 循环等待任务完成

    我创建了一个 bash 脚本来处理文件夹及其子文件夹中的视频 find type f name mkv while read file do ffmpeg i file done 问题 它不是 while 循环等待 ffmpeg 完成 而是
  • 如何使用bash脚本获取分区的偏移量?

    我可以用parted找出我的图像的偏移量 sudo parted s image img unit B print Model file Disk home user image img 107374182400B Sector size
  • 在 Bash 中替换垂直线

    我很难完成我的脚本 因为这一部分没有按照我想要的方式运行 我的脚本中有这一行 cat home tmp temp1 txt awk gsub RS gsub RS print gt home tmp temp txt 效果很好 是的 但是当
  • 如何用awk删除以“C”开头的行?

    如何使用以下命令从文本文件中删除以 C 开头的行awk 有什么建议请 如果数据在文件中data txt then With awk awk C data txt With grep grep v C data txt 显示开头不带 C 的所
  • 添加文件时运行 shell 命令

    我的 Linux 机器上有一个名为 images 的文件夹 该文件夹连接到一个网站 该网站的管理员可以向该网站添加图片 但是 当添加图片时 我想要一个命令来运行调整目录中所有图片的大小 简而言之 我想知道当新文件添加到特定位置时如何使服务器
  • Python DNS服务器IP地址查询

    我正在尝试使用 python 获取 DNS 服务器 IP 地址 要在 Windows 命令提示符下执行此操作 我将使用 ipconfig 全部 如下所示 我想使用 python 脚本做同样的事情 有什么方法可以提取这些值吗 我成功提取了设备
  • 如何安装 grunt-cli 而不出现错误?

    灵感来自 Chris Coyierpost http 24ways org 2013 grunt is not weird and hard 我决定尝试一下 grunt 但我在设置时遇到了很大的问题 首先 我安装了 Node js 然后我将
  • 使用 shell 脚本将行附加到 /etc/hosts 文件

    我有一个新的 Ubuntu 12 04 VPS 我正在尝试编写一个安装脚本来完成整个 LAMP 安装 我遇到问题的地方是在 etc hosts文件 我当前的主机文件如下所示 127 0 0 1 localhost Venus The fol
  • 在java中执行外部程序并传递命令

    我有这个国际象棋引擎 Rybka exe 我必须在 java 中执行 以下是如何运行 Rybka 的示例 单击它后 控制台将打开并等待输入 然后你输入 uci 并按 Enter 键并等待它加载 大约 1 秒 然后你必须输入更多行作为选项和内
  • 如何设置 tmux 在启动时打开指定的窗口?

    如何设置 tmux 使其在启动时打开指定的窗口 您可以编写一个小 shell 脚本来启动 tmux 以及所需的程序 我在一个名为 dev tmux 的 shell 脚本中包含以下内容 开发环境 bin sh tmux new session
  • 在 AIX 中使用 Mailx 通过电子邮件发送 SQLPlus 查询结果的 Shell 脚本

    我有我需要的命令 如果我在提示符下执行这些命令 一切都会按预期进行 SQLPlus 运行查询 将结果导出到文件 然后 Mailx 将该文件通过电子邮件发送给我 sqlplus username pwd instance SPOOL home
  • 如何在 *nix 中登录时运行脚本?

    我知道我曾经知道如何做到这一点 但是 如何在 unix 中登录时运行脚本 bash 可以 From 维基百科 Bash http en wikipedia org wiki Bash 28Unix shell 29 当 Bash 启动时 它

随机推荐

  • JS中的逻辑与和逻辑或

    JS中的逻辑或 符号 从字面上来说 只有前后都是 false 的时候才返回 false 否则返回 true console log 5 gt 6 6 gt 5 返回true 5 gt 6为false 但是 6 gt 5为true 所以返回
  • python-selenium页面定位不到元素

    1 查看是否有新的url打开 当前页面 mainHandle driver current window handle 获取所有的handle Handles driver window handles 循环遍历 找到不是当前页面的就切换
  • vue获取元素offsetTop,mounted获取不到offsetTop,获取元素距离页面顶边距离

    记录一下开发过程中遇到的坑 今天想做一个功能 当我评论完之后 页面跳到评论区顶部 于是就要获取到评论区距离页面顶部的距离 需要循环获取offsetTop来实现 但是在mounted阶段是无论如何都获取不到offsetParent的 不管是
  • C# 对数据库操作的函数总结

    SqlCommand ExecuteNonQuery 方法对连接执行 Transact SQL 语句并返回受影响的行数 可以写也可以读 1 可以使用ExecuteNonQuery 来执行目录操作 例如查询数据库的结构或创建诸如表等的数据库对
  • Unet 语义分割模型(Keras)

    文章目录 前言 一 什么是语义分割 二 Unet 1 基本原理 2 mini unet 3 Mobilenet unet 4 数据加载部分 参考 前言 最近由于在寻找方向上迷失自我 准备了解更多的计算机视觉任务重的模型 看到语义分割任务重U
  • BAT文件里注释符号

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 在BAT文件批处理中注释的方式如下 1 注释内容 第一个冒号后也可以跟任何一个非字母数字的字符 2 rem 注释内容 不能出现重定向符号和管道符号 3 echo 注释内容
  • nginx配置https访问

    01 http https HTTP HyperText Transfer Protocol 超文本传输协议 是一种用于分布式 协作式和超媒体信息系统的应用层协议 简单来说就是一种发布和接收 HTML 页面的方法 被用于在 Web 浏览器和
  • 在ubuntu上安装splint

    lint lint是最著名的C语言工具之一 是由贝尔实验室SteveJohnson于1979在PCC PortableC Compiler 基础上开发的静态代码分析 一般由UNIX系统提供 工具介绍 与大多数C语言编译器相比 lint可以对
  • 试图理解 Decagon(二)具体方法

    4 图卷积 Deacgon 方法 综述 关系被表示为一个图 G V R 其中 节点N 蛋白质 药物 vi V 和标记的边 vi r vj r代表边的类型 分别由 蛋白质间的作用 某种药物 与其作用蛋白质间的关系 存在于某两种药物间的副作用关
  • SQLSERVER登录与JDBC连接事宜

    这半天都在帮副主席搞这个 比较最重要的两个点 SQLServer创建用户登录 https www cnblogs com vuenote p 10143434 html 使用JDBC连接SQLSERVER数据库 https www cnbl
  • C51单片机期末复习第八章单片机接口技术

    一 总线 传送同类信息的连线 三总线 地址总线AB 数据总线DB 控制总线CB 目录 ppt给的没啥用 乱还不全 8 1 单片机的系统总线 8 2 简单并行I O口扩展 8 3 可编程并行I O口扩展 8 4 D A转换与DAC0832应用
  • vue 自定义月日历日程组件(MSchedule)

    效果图 组件的使用 日程内容可以自定义 状态对应颜色可以自定义
  • vue 动态组件component标签

    vue 提供了一个内置的
  • python笔记:#013#高级变量类型

    高级变量类型 目标 列表 元组 字典 字符串 公共方法 变量高级 知识点回顾 Python 中数据类型可以分为 数字型 和 非数字型 数字型 整型 int 浮点型 float 布尔型 bool 真 True 非 0 数 非零即真 假 Fal
  • Ubuntu root账户登陆电脑

    vi etc pam d gdm autologin 屏蔽 auth required pam succeed if so user root quiet success vi etc pam d gdm password 屏蔽auth r
  • nextLine().split(“[\\s]“)的意思

    Scanner sc new Scanner System in String a sc nextLine split s 这句话的意思是 把输入的字符串以 s 为条件分割成一个String数组 s表示空格 回车 换行等空白符 当然 单表示
  • 学python的第十五天---简单数论

    模运算 一 刷题统计 二 快速幂 三 RSA解密 GCD LCM 四 核桃的数量 最小公倍数 五 Hankson 的趣味题 六 寻找整数 素数 七 笨小孩 八 质数 九 分解质因数 模运算 ab mod m a mod m b mod m
  • Java实现比较版本号

    涉及到客户端的系统中经常需要用到比较版本号的功能 但是比较版本号又不能完全按照字符串比较的方式去用compareTo之类的方法 这就需要我们总结版本号的通用规则 设计一个比较算法并封装成通用方法来使用 通常版本号如 1 3 20 8 6 8
  • RS-485总线前世今生;

    一 RS232和RS485的区别 RS 232采取的是单端不平衡传输方式 其收发端的数据信号都是相对于地信号的 所以共模抑制能力 差 再加上双绞线分布电容的影响 其最大传输距离仅为15米 最高传输速率只有20kbit s 2560Byte
  • bash脚本调试方法

    本文全面系统地介绍了shell脚本调试技术 包括使用echo tee trap等命令输出关键信息 跟踪变量的值 在脚本中植入调试钩子 使用 n 选项进行shell脚本的语法检查 使用 x 选项实现shell脚本逐条语句的跟踪 巧妙地利用sh