Linux shell 脚本编程-基础篇 (一)

shell编程(一)—— 基础篇 Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问 Linux 内核的服务。Shell 脚本(shell script),是一种为 shell 编写的脚本程序,一般文件后缀为 .sh。 阅读详情

1. 构建基本脚本



1.1 使用多个命令


shell 脚本的关键在于输入多个命令并处理每个命令的结果,甚至需要将一个命令的结果传给另一个命令。shell可以让将多个命令串起来,一次执行完成。
如果要两个命令一起运行,可以把它们放在同一行中,彼此间用分号隔开。

    [root@devalone testdir]# date; who
    2018年 07月 04日 星期三 19:56:07 CST
    devalone pts/0        2018-07-04 09:17 (192.168.1.101)

使用这种办法就能将任意多个命令串连在一起使用了,只要不超过最大命令行字符数 255 就行。

这种技术对于小型脚本尚可,但它有一个很大的缺陷:每次运行之前,都必须在命令提示符下输入整个命令。可以将这些命令组合成一个简单的文本文件,
这样就不需要在命令行中手动输入了。在需要运行这些命令时,只用运行这个文本文件就行了。


1.2 创建 shell 脚本文件
-----------------------------------------------------------------------------------------------------------------------------------------
要将 shell 命令放到文本文件中,需要用文本编辑器来创建一个文件,然后将命令输入到文件中。

通常以 .sh 作为文件后缀名,也可以没有后缀名。

在创建shell脚本文件时,必须在文件的第一行指定要使用的shell。其格式为:

#!/bin/bash

在通常的shell脚本中,井号(#)用作注释行。shell 并不会处理 shell 脚本中的注释行。然而,shell脚本文件的第一行是个例外,# 后面的惊叹号会告诉
shell 用哪个 shell 来运行脚本(可以使用 bash shell,也可以使用另一个 shell 来运行脚本)。

注释内容:建议养成良好的脚本编写习惯,在每个 script 文件头处记录好如下内容:
    
    ● script 功能
    ● script 版本信息
    ● script 作者与联系方式
    ● script 版权声明
    ● script 历史版本信息
    ● script 内较特殊的指令,使用绝对路径表达
    ● script 运行时所需的环境变量声明与设置

在指定了 shell 之后,就可以在文件的每一行中输入命令,然后加一个回车符。注释可用#添加。
示例:

    #!/bin/bash
    # This script displays the date and who's log on
    echo -n  "The time and date are: "
    date
    echo "Let's see who's logged into the system:"
    who

可以根据需要,使用分号将两个命令放在一行上,但在 shell 脚本中,可以在独立的行中书写命令。shell 会按根据命令在文件中出现的顺序进行处理。

要注意另有一行也以 # 开头,并添加了一个注释。shell 不会解释以 # 开头的行(除了以 #! 开头的第一行)。留下注释来说明脚本做了什么,这种方法
非常好。

要执行脚本文件需要处理两件事:

    
    第一,要让 shell 找到脚本文件
    -------------------------------------------------------------------------------------------------------------------------------------
    要让 bash shell 能找到要执行的脚本文件。需采取以下两种做法之一:

        ● 将 shell 脚本文件所处的目录添加到 PATH 环境变量中;
        ● 在提示符中用绝对或相对文件路径来引用 shell 脚本文件。

    为了引用当前目录下的文件,可以在 shell 中使用单点操作符。

    
    第二,要保证脚本文件对执行者有执行权限
    -------------------------------------------------------------------------------------------------------------------------------------
    通过 chmod 命令赋予用户执行文件的权限:

    [devalone@devalone shell-script]$ chmod a+x test1.sh
    [devalone@devalone shell-script]$ ls -l test1.sh
    -rwxrwxr-x. 1 devalone devalone 152 1月   2 2018 test1.sh


    
■ 脚本的执行规则
-----------------------------------------------------------------------------------------------------------------------------------------
脚本执行遵循如下规则:

    (1) 指令的执行从上而下、从左而右分析执行;
    (2) 指令、选项与参数间的多个空白会被忽略掉;
    (3) 空白行也被忽略掉,[tab] 键空白被视为空格;    
    (4) 读到 Enter 键符号(CR)时,尝试开始执行该行或该串命令;
    (5) 如果一行内容太多,可以使用 "\Enter" 符号来延伸至下一行;
    (6) "#" 被视为注释,任何加在 # 后面的文本被视为注释而被忽略。


■ 脚本执行方法
-----------------------------------------------------------------------------------------------------------------------------------------
    ● 直接下达指令:在子进程中执行脚本
        
        绝对路径:/home/devalone/shell.sh
        相对路径:./shell.sh
        环境变量 "PATH" 所包含的路径:shell.sh

    ● 以 bash 程序来执行: 在子进程中执行脚本
            
        bash shell.sh
        sh shell.sh
    
        观查:
            [devalone@devalone 19]$ which sh
            /usr/bin/sh
            [devalone@devalone 19]$ ll /usr/bin/sh
            lrwxrwxrwx. 1 root root 4 9月  30 2016 /usr/bin/sh -> bash
        
            sh 是 bash 的连接,因此 sh 可以直接执行脚本。
    
    ● source 或 .    :在父进程中执行脚本
    
        source shell.sh
        . shell.sh

        
■ 脚本的追踪与 debug
-----------------------------------------------------------------------------------------------------------------------------------------    
script 在执行之前,通过 bash 相关参数判断可以判断脚本中是否有语法错误。

[devalone@devalone shell-script]$ sh [-nvx] scripts.sh

选项:
    -n :不执行 script,仅检查语法问题;
    -v :在执行 sccript 之前,先将 scripts 的内容输出到屏幕上;
    -x :将 script 的执行过程显示到屏幕上。
    
示例: 检查 test1.sh 是否有语法问题

    [devalone@devalone shell-script]$ sh -n test1.sh
    [devalone@devalone shell-script]$ 语法没有问题,不会显示任何信息
    
    
示例:使用 -v 选项显示脚本内容及其执行过程

    [devalone@devalone shell-script]$ sh -v test1.sh
    module () {  eval `/usr/bin/modulecmd bash $*`
    }
    scl () {  local CMD=$1;
     if [ "$CMD" = "load" -o "$CMD" = "unload" ]; then
     eval "module $@";
     else
     /usr/bin/scl "$@";
     fi
    }
    #!/bin/bash

    # This script displays the date and who's log on
    echo -n  "The time and date are: "
    The time and date are: date
    2018年 07月 10日 星期二 15:53:27 CST
    echo "Let's see who's logged into the system:"
    Let's see who's logged into the system:
    who
    devalone pts/0        2018-07-10 10:18 (192.168.1.101)


示例: 将 test1.sh 的执行过程显示到屏幕上:

    [devalone@devalone shell-script]$ sh -x test1.sh
    + echo -n 'The time and date are: '
    The time and date are: + date
    2018年 07月 10日 星期二 15:50:31 CST
    + echo 'Let'\''s see who'\''s logged into the system:'
    Let's see who's logged into the system:
    + who
    devalone pts/0        2018-07-10 10:18 (192.168.1.101)

 


1.3 显示消息
-----------------------------------------------------------------------------------------------------------------------------------------
在 echo 命令后面加上了一个字符串,该命令就能显示出这个文本字符串。

    [devalone@devalone shell-script]$ echo this is a test
    this is a test

默认情况下,不需要使用引号将要显示的文本字符串划定出来。但有时在字符串中出现引号的话就比较麻烦了。echo 命令可用单引号或双引号来划定文本
字符串。如果在字符串中用到了它们,需要在文本中使用其中一种引号,而用另外一种来将字符串划定起来。

    [devalone@devalone shell-script]$ echo "This is a test to see if you're paying attention"
    This is a test to see if you're paying attention

可以将 echo 语句添加到 shell 脚本中任何需要显示额外信息的地方。

    [devalone@devalone shell-script]$ cat test1.sh
    #!/bin/bash
    
    # This script displays the date and who's log on
    echo -n  "The time and date are: "
    date
    echo "Let's see who's logged into the system:"
    who

设置 PATH 环境变量:将当前工作目录加入 PATH 路径中。
    
    [devalone@devalone shell-script]$ PATH=$PATH:.
    
运行:
    [devalone@devalone shell-script]$ test1.sh
    The time and date are: 2018年 07月 04日 星期三 20:23:44 CST
    Let's see who's logged into the system:
    devalone pts/0        2018-07-04 09:17 (192.168.1.101)

如果想把文本字符串和命令输出显示在同一行中,可以用 echo 语句的 -n 参数。只要将第一个 echo 语句改成这样就行:
如上例所示。

 

1.4 使用变量
-----------------------------------------------------------------------------------------------------------------------------------------
变量允许临时性地将信息存储在 shell 脚本中,以便和脚本中的其他命令一起使用。


1.4.1 环境变量
-----------------------------------------------------------------------------------------------------------------------------------------
Linux 系统的环境变量,也可以在脚本中访问。

shell 维护着一组环境变量,用来记录特定的系统信息。比如系统的名称、登录到系统上的用户名、用户的系统ID(也称为UID)、用户的默认主目录以及
shell 查找程序的搜索路径。可以用 set 命令来显示一份完整的当前环境变量列表。

    [devalone@devalone ~]$ set
    BASH=/bin/bash
    BASHOPTS=checkwinsize:cmdhist:complete_fullquote:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments
    :login_shell:progcomp:promptvars:sourcepath
    BASH_ALIASES=()
    BASH_ARGC=()
    BASH_ARGV=()
    BASH_CMDS=()
    BASH_COMPLETION_COMPAT_DIR=/etc/bash_completion.d
    BASH_LINENO=()
    BASH_REMATCH=()
    BASH_SOURCE=()
    BASH_VERSINFO=([0]="4" [1]="3" [2]="42" [3]="1" [4]="release" [5]="x86_64-redhat-linux-gnu")
    BASH_VERSION='4.3.42(1)-release'
    CATALINA_HOME=/home/devalone/programs/apache-tomcat-8.5.11
    COLUMNS=130
    COMP_WORDBREAKS=$' \t\n"\'><=;|&(:'
    DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
    DIRSTACK=()
    EUID=1000
    GROUPS=()
    HISTCONTROL=ignoredups
    HISTFILE=/home/devalone/.bash_history
    HISTFILESIZE=1000
    HISTSIZE=1000
    HOME=/home/devalone
    HOSTNAME=devalone.sansovo.org
    ...

在脚本中,可以在环境变量名称之前加上美元符($)来使用这些环境变量:
    
    [devalone@devalone shell-script]$ cat test2.sh
    #!/bin/bash
    # display user information from the system.
    echo "User info for userid: $USER"
    echo UID: $UID
    echo HOME: $HOME

$USER、$UID 和 $HOME 环境变量用来显示已登录用户的有关信息。脚本输出如下:

    [devalone@devalone shell-script]$ ./test2.sh
    User info for userid: devalone
    UID: 1000
    HOME: /home/devalone

注意,echo 命令中的环境变量会在脚本运行时替换成当前值。另外,在第一个字符串中可以将 $USER 系统变量放置到双引号中,而 shell 依然能够知道
我们的意图。


    NOTE:
    -------------------------------------------------------------------------------------------------------------------------------------
    可以通过 ${variable} 形式引用的变量。变量名两侧额外的花括号通常用来帮助识别美元符后的变量名。
    
    
1.4.2 用户变量
-----------------------------------------------------------------------------------------------------------------------------------------
除了环境变量,shell 脚本还允许在脚本中定义和使用自己的变量。定义变量允许临时存储数据并在整个脚本中使用,从而使shell脚本看起来更像一个真正
的计算机程序。

用户变量可以是任何由字母、数字或下划线组成的文本字符串,长度不超过20个。用户变量区分大小写。

使用等号将值赋给用户变量。在变量、等号和值之间不能出现空格。

示例:

    var1=10
    var2=-57
    var3=testing
    var4="still more testing"

shell 脚本会自动决定变量值的数据类型。在脚本的整个生命周期里,shell 脚本中定义的变量会一直保持着它们的值,但在shell脚本结束时会被删除掉。

与系统变量类似,用户变量可通过美元符 ($) 引用。

示例:
    [devalone@devalone shell-script]$ cat test3.sh
    #!/bin/bash
    # testing variables
    days=10
    guest="Katie"
    echo "$guest checked in $days days ago"

    days=5
    guest="Jessical"
    echo "$guest checked in $days days ago"

运行:
    [devalone@devalone shell-script]$ ./test3.sh
    Katie checked in 10 days ago
    Jessical checked in 5 days ago

变量每次被引用时,都会输出当前赋给它的值。重要的是要记住,引用一个变量值时需要使用美元符,而引用变量来对其进行赋值时则不要使用美元符。

示例:
    [devalone@devalone shell-script]$ cat test4.sh
    #!/bin/bash
    # assigning a variable value to another variable

    value1=10
    value2=$value1
    echo The resulting value is $value2

在赋值语句中使用value1变量的值时,仍然必须用美元符。

运行:
    [devalone@devalone shell-script]$ ./test4.sh
    The resulting value is 10

没有美元符,shell 会将变量名解释成普通的文本字符串,通常这并不是想要的结果。


1.4.3 命令替换
-----------------------------------------------------------------------------------------------------------------------------------------
shell 脚本中最有用的特性之一就是可以从命令输出中提取信息,并将其赋给变量。把输出赋给变量之后,就可以随意在脚本中使用了。这个特性在处理脚本
数据时尤为方便。

有两种方法可以将命令输出赋给变量:

    □ 反引号字符(`)
    □ $()格式

命令替换允许用户将 shell 命令的输出赋给变量。

用一对反引号把整个命令行命令围起来:

    testing='date'
    
使用$()格式:

    testing=$(date)

shell 会运行命令替换符号中的命令,并将其输出赋给变量 testing。注意,赋值等号和命令替换字符之间没有空格。

    [devalone@devalone shell-script]$ cat test5.sh
    #!/bin/bash
    testing=$(date)
    echo "The date and time are: " $testing

变量 testing 获得了 date 命令的输出,然后使用 echo 语句显示出它的值。

运行:
    [devalone@devalone shell-script]$ ./test5.sh
    The date and time are:  2018年 07月 05日 星期四 11:31:37 CST

示例:
    [devalone@devalone shell-script]$ cat test6.sh
    #!/bin/bash
    # copy the /usr/bin directory listing to a log file
    today=$(date +%y%m%d)
    ls /usr/bin -al > log.$today

在脚本中通过命令替换获得当前日期并用它来生成唯一文件名。today 变量是被赋予格式化后的 date 命令的输出。这是提取日期信息来生成日志文件名常用
的一种技术。+%y%m%d格式告诉date命令将日期显示为两位数的年月日的组合。

运行:
    [devalone@devalone shell-script]$ ./test6.sh
    [devalone@devalone shell-script]$ ls -l log*
    -rw-rw-r--. 1 devalone devalone 122402 7月   5 11:45 log.180705

生成了以当前日期作为文件名后缀的文件:log.180705


    NOTE:
    -------------------------------------------------------------------------------------------------------------------------------------
    命令替换会创建一个子shell 来运行对应的命令。子shell(subshell)是由运行该脚本的 shell 所创建出来的一个独立的子shell(child shell)。
    正因如此,由该子shell 所执行命令是无法使用脚本中所创建的变量的。
    
    在命令行提示符下使用路径./运行命令的话,也会创建出子shell;要是运行命令的时候不加入路径,就不会创建子shell。如果使用的是内建的 shell
    命令,并不会涉及子shell。
    
    
1.5 重定向输入和输出
-----------------------------------------------------------------------------------------------------------------------------------------
有些时候想要保存某个命令的输出而不仅仅只是让它显示在显示器上。bash shell提供了几个操作符,可以将命令的输出重定向到另一个位置(比如文件)。
重定向可以用于输入,也可以用于输出,可以将文件重定向到命令输入。


1.5.1 输出重定向
-----------------------------------------------------------------------------------------------------------------------------------------
最基本的重定向将命令的输出发送到一个文件中。bash shell 用大于号(>)来完成这项功能:

    command > outputfile

示例:
    [devalone@devalone shell-script]$ date > testdate
    [devalone@devalone shell-script]$ ls -l testdate
    -rw-rw-r--. 1 devalone devalone 43 7月   5 11:58 testdate

    [devalone@devalone shell-script]$ cat testdate
    2018年 07月 05日 星期四 11:58:19 CST

重定向操作符创建了一个文件 testdate(通过默认的 umask 设置),并将 date 命令的输出重定向到该文件中。如果输出文件已经存在了,重定向操作符
会用新的文件数据覆盖已有文件。    

示例:
    [devalone@devalone shell-script]$ who >testdate
    [devalone@devalone shell-script]$ cat testdate
    devalone pts/0        2018-07-05 11:05 (192.168.1.101)

testdate 内容被覆盖。

如果不想覆盖文件原有内容,而是想要将命令的输出追加到已有文件中,比如正在创建一个记录系统上某个操作的日志文件。在这种情况下,可以用双大于号
>> 来追加数据。

示例:
    [devalone@devalone shell-script]$ date >> testdate
    [devalone@devalone shell-script]$ cat testdate
    devalone pts/0        2018-07-05 11:05 (192.168.1.101)
    2018年 07月 05日 星期四 12:03:51 CST


1.5.2 输入重定向
-----------------------------------------------------------------------------------------------------------------------------------------
输入重定向和输出重定向正好相反。输入重定向将文件的内容重定向到命令,而非将命令的输出重定向到文件。

输入重定向符号是小于号(<):

    command < inputfile

一个简单的记忆方法就是:在命令行上,命令总是在左侧,而重定向符号 "指向" 数据流动的方向。小于号说明数据正在从输入文件流向命令。

示例:
    [devalone@devalone shell-script]$ wc < testdate
     2 11 98

wc 命令可以对对数据中的文本进行计数。默认情况下,它会输出3个值:

    □ 文本的行数
    □ 文本的词数
    □ 文本的字节数
    
通过将文本文件重定向到 wc 命令,立刻就可以得到文件中的行、词和字节的计数。这个例子说明 testdate 文件有2行、11个 单词以及 98 字节。

还有另外一种输入重定向的方法,称为内联输入重定向(inline input redirection)。这种方法无需使用文件进行重定向,只需要在命令行中指定用于输入
重定向的数据就可以了。

内联输入重定向符号是远小于号(<<)。除了这个符号,必须指定一个文本标记来划分输入数据的开始和结尾。任何字符串都可作为文本标记,但在数据的
开始和结尾文本标记必须一致。

命令格式:

    command << marker
    data
    marker
    
在命令行上使用内联输入重定向时,shell 会用 PS2 环境变量中定义的次提示符来提示输入数据。下面是它的使用情况。    

示例:

    [devalone@devalone shell-script]$ wc << EOF
    > test string 1
    > test string 2
    > test string 3
    > EOF
     3  9 42

次提示符会持续提示,以获取更多的输入数据,直到输入了作为文本标记的那个字符串。wc 命令会对内联输入重定向提供的数据进行行、词和字节计数。


1.6 管道
-----------------------------------------------------------------------------------------------------------------------------------------
有时需要将一个命令的输出作为另一个命令的输入。这可以用重定向来实现,只是有些笨拙。

如:
    [devalone@devalone shell-script]$ rpm -qa > rpm.list
    [devalone@devalone shell-script]$ sort < rpm.list
    aajohan-comfortaa-fonts-2.004-6.fc24.noarch
    abattis-cantarell-fonts-0.0.24-1.fc24.noarch
    abrt-2.8.2-1.fc24.x86_64
    abrt-addon-ccpp-2.8.2-1.fc24.x86_64
    abrt-addon-coredump-helper-2.8.2-1.fc24.x86_64
    abrt-addon-kerneloops-2.8.2-1.fc24.x86_64
    abrt-addon-pstoreoops-2.8.2-1.fc24.x86_64
    abrt-addon-python3-2.8.2-1.fc24.x86_64
    abrt-addon-vmcore-2.8.2-1.fc24.x86_64
    abrt-addon-xorg-2.8.2-1.fc24.x86_64
    abrt-cli-2.8.2-1.fc24.x86_64
    abrt-dbus-2.8.2-1.fc24.x86_64
    abrt-desktop-2.8.2-1.fc24.x86_64
    ...

这种方法的确管用,但仍然是一种比较繁琐的信息生成方式。我们用不着将命令输出重定向到文件中,可以将其直接重定向到另一个命令。这个过程叫作
管道连接(piping)。

管道被放在命令之间,将一个命令的输出重定向到另一个命令中:

    command1 | command2
    
不要以为由管道串起的两个命令会依次执行。Linux 系统实际上会同时运行这两个命令,在系统内部将它们连接起来。在第一个命令产生输出的同时,输出
会被立即送给第二个命令。数据传输不会用到任何中间文件或缓冲区。

    示例:
    [devalone@devalone shell-script]$ rpm -qa | sort
    aajohan-comfortaa-fonts-2.004-6.fc24.noarch
    abattis-cantarell-fonts-0.0.24-1.fc24.noarch
    abrt-2.8.2-1.fc24.x86_64
    abrt-addon-ccpp-2.8.2-1.fc24.x86_64
    abrt-addon-coredump-helper-2.8.2-1.fc24.x86_64
    abrt-addon-kerneloops-2.8.2-1.fc24.x86_64
    abrt-addon-pstoreoops-2.8.2-1.fc24.x86_64
    abrt-addon-python3-2.8.2-1.fc24.x86_64
    abrt-addon-vmcore-2.8.2-1.fc24.x86_64
    abrt-addon-xorg-2.8.2-1.fc24.x86_64
    abrt-cli-2.8.2-1.fc24.x86_64
    abrt-dbus-2.8.2-1.fc24.x86_64
    abrt-desktop-2.8.2-1.fc24.x86_64
    abrt-gui-2.8.2-1.fc24.x86_64
    abrt-gui-libs-2.8.2-1.fc24.x86_64
    ...


可以在一条命令中使用任意多条管道。可以持续地将命令的输出通过管道传给其他命令来细化操作。

示例:
    
    [devalone@devalone shell-script]$ rpm -qa | sort | less
    aajohan-comfortaa-fonts-2.004-6.fc24.noarch
    abattis-cantarell-fonts-0.0.24-1.fc24.noarch
    abrt-2.8.2-1.fc24.x86_64
    abrt-addon-ccpp-2.8.2-1.fc24.x86_64
    abrt-addon-coredump-helper-2.8.2-1.fc24.x86_64
    abrt-addon-kerneloops-2.8.2-1.fc24.x86_64
    abrt-addon-pstoreoops-2.8.2-1.fc24.x86_64
    abrt-addon-python3-2.8.2-1.fc24.x86_64
    abrt-addon-vmcore-2.8.2-1.fc24.x86_64
    abrt-addon-xorg-2.8.2-1.fc24.x86_64
    abrt-cli-2.8.2-1.fc24.x86_64
    abrt-dbus-2.8.2-1.fc24.x86_64
    abrt-desktop-2.8.2-1.fc24.x86_64
    abrt-gui-2.8.2-1.fc24.x86_64
    abrt-gui-libs-2.8.2-1.fc24.x86_64
    ...


也可以搭配使用重定向和管道来将输出保存到文件中:

    [devalone@devalone shell-script]$ rpm -qa | sort | less
    [devalone@devalone shell-script]$ rpm -qa | sort > rpm.list
    [devalone@devalone shell-script]$ less rpm.list
    aajohan-comfortaa-fonts-2.004-6.fc24.noarch
    abattis-cantarell-fonts-0.0.24-1.fc24.noarch
    abrt-2.8.2-1.fc24.x86_64
    abrt-addon-ccpp-2.8.2-1.fc24.x86_64
    abrt-addon-coredump-helper-2.8.2-1.fc24.x86_64
    abrt-addon-kerneloops-2.8.2-1.fc24.x86_64
    abrt-addon-pstoreoops-2.8.2-1.fc24.x86_64
    abrt-addon-python3-2.8.2-1.fc24.x86_64
    abrt-addon-vmcore-2.8.2-1.fc24.x86_64
    abrt-addon-xorg-2.8.2-1.fc24.x86_64
    abrt-cli-2.8.2-1.fc24.x86_64
    abrt-dbus-2.8.2-1.fc24.x86_64
    abrt-desktop-2.8.2-1.fc24.x86_64
    abrt-gui-2.8.2-1.fc24.x86_64
    abrt-gui-libs-2.8.2-1.fc24.x86_64
    ...

rpm.list文件中的数据现在已经排好序了。


1.7 执行数学运算
-----------------------------------------------------------------------------------------------------------------------------------------
另一个对任何编程语言都很重要的特性是操作数字的能力。遗憾的是,对 shell 脚本来说,这个处理过程会比较麻烦。在 shell 脚本中有两种途径来进行
数学运算。


1.7.1 expr 命令
-----------------------------------------------------------------------------------------------------------------------------------------
最开始,Bourne shell 提供了一个特别的命令用来处理数学表达式。expr 命令允许在命令行上处理数学表达式,但是特别笨拙。

    [devalone@devalone shell-script]$ expr 1 + 5
    6

expr 命令能够识别少数的数学和字符串操作符,见下表:

    expr 命令操作符
    +---------------------------+-----------------------------------------------------------------------
    | 操 作 符                    | 描 述
    +---------------------------+-----------------------------------------------------------------------
    | ARG1 | ARG2                | 如果ARG1既不是null也不是零值,返回ARG1;否则返回ARG2
    +---------------------------+-----------------------------------------------------------------------
    | ARG1 & ARG2                | 如果没有参数是null或零值,返回ARG1;否则返回0
    +---------------------------+-----------------------------------------------------------------------
    | ARG1 < ARG2                | 如果ARG1小于ARG2,返回1;否则返回0
    +---------------------------+-----------------------------------------------------------------------
    | ARG1 <= ARG2                | 如果ARG1小于或等于ARG2,返回1;否则返回0
    +---------------------------+-----------------------------------------------------------------------
    | ARG1 = ARG2                | 如果ARG1等于ARG2,返回1;否则返回0
    +---------------------------+-----------------------------------------------------------------------
    | ARG1 != ARG2                | 如果ARG1不等于ARG2,返回1;否则返回0
    +---------------------------+-----------------------------------------------------------------------
    | ARG1 >= ARG2                | 如果ARG1大于或等于ARG2,返回1;否则返回0
    +---------------------------+-----------------------------------------------------------------------
    | ARG1 > ARG2                | 如果ARG1大于ARG2,返回1;否则返回0
    +---------------------------+-----------------------------------------------------------------------
    | ARG1 + ARG2                | 返回ARG1和ARG2的算术运算和
    +---------------------------+-----------------------------------------------------------------------
    | ARG1 - ARG2                | 返回ARG1和ARG2的算术运算差
    +---------------------------+-----------------------------------------------------------------------
    | ARG1 * ARG2                | 返回ARG1和ARG2的算术乘积
    +---------------------------+-----------------------------------------------------------------------
    | ARG1 / ARG2                | 返回ARG1被ARG2除的算术商
    +---------------------------+-----------------------------------------------------------------------
    | ARG1 % ARG2                | 返回ARG1被ARG2除的算术余数
    +---------------------------+-----------------------------------------------------------------------
    | STRING : REGEXP            | 如果REGEXP匹配到了STRING中的某个模式,返回该模式匹配
    +---------------------------+-----------------------------------------------------------------------
    | match STRING REGEXP        | 如果REGEXP匹配到了STRING中的某个模式,返回该模式匹配
    +---------------------------+-----------------------------------------------------------------------
    | substr STRING POS LENGTH    | 返回起始位置为POS(从1开始计数)、长度为LENGTH个字符的子字符串        
    +---------------------------+-----------------------------------------------------------------------
    | index STRING CHARS        | 返回在STRING中找到CHARS字符串的位置;否则,返回0
    +---------------------------+-----------------------------------------------------------------------
    | length STRING                | 返回字符串STRING的数值长度
    +---------------------------+-----------------------------------------------------------------------
    | + TOKEN                    | 将TOKEN解释成字符串,即使是个关键字
    +---------------------------+-----------------------------------------------------------------------
    | (EXPRESSION)                | 返回EXPRESSION的值
    +---------------------------+-----------------------------------------------------------------------
    
expr 支持模式匹配和字符串操作。字符串表达式的优先级高于数值表达式和逻辑关系表达式。
 
'STRING : REGEX'
     执行模式匹配。两端参数会转换为字符格式,且第二个参数被视为正则表达式(GNU基本正则),它默认会隐含前缀"^"。随后将第一个参数和正则模式做匹配。
 
     如果匹配成功,且REGEX使用了'\('和'\)',则此表达式返回匹配到的,如果未使用'\('和'\)',则返回匹配的字符数。
 
     如果匹配失败,如果REGEX中使用了'\('和'\)',则此表达式返回空字符串,否则返回为0。
 
     只有第一个'\(...\)'会引用返回的值;其余的'\(...\)'只在正则表达式分组时有意义。
 
     在正则表达式中,'\+','\?'和'\|'分表代表匹配一个或多个,0个或1个以及两端任选其一的意思。
 
'match STRING REGEX'
     等价于'STRING : REGEX'。
 
'substr STRING POSITION LENGTH'
     返回STRING字符串中从POSITION开始,长度最大为LENGTH的子串。如果POSITION或LENGTH为负数,0或非数值,则返回空字符串。
 
'index STRING CHARSET'
     CHARSET中任意单个字符在STRING中最前面的字符位置。如果在STRING中完全不存在CHARSET中的字符,则返回0。见后文示例。
    
'length STRING'
     返回STRING的字符长度。
 
'+ TOKEN'
     将TOKEN解析为普通字符串,即使TOKEN是像MATCH或操作符"/"一样的关键字。这使得'expr length + "$x"'或'expr + "$x" : '.*/\(.\)''可以正常被测试,即使"$x"的值可能是'/'或'index'关键字。这个操作符是一个GUN扩展。
     通用可移植版的应该使用'" $token" : ' \(.*\)''来代替'+ "$token"'。
 
   要让expr将关键字解析为普通的字符,必须使用引号包围。
   

尽管标准操作符在 expr 命令中工作得很好,但在脚本或命令行上使用它们时仍有问题出现。许多 expr 命令操作符在shell中另有含义(比如星号)。
当它们出现在在 expr 命令中时,会得到一些诡异的结果。

示例:
    [devalone@devalone shell-script]$ expr 5 * 2
    expr: 语法错误

要解决这个问题,对于那些容易被 shell 错误解释的字符,在它们传入 expr 命令之前,需要使用 shell 的转义字符(反斜线)将其标出来。

    [devalone@devalone shell-script]$ expr 5 \* 2
    10

在shell脚本中使用expr命令也同样复杂:

    [devalone@devalone shell-script]$ cat test6
    #!/bin/bash
    # An example of using the expr command
    var1=10
    var2=20
    var3=$(expr $var2 / $var1)
    echo The result is $var3

要将一个数学算式的结果赋给一个变量,需要使用命令替换来获取 expr 命令的输出:

运行:
    [devalone@devalone shell-script]$ test6
    The result is 2


1.7.2 使用方括号[]
-----------------------------------------------------------------------------------------------------------------------------------------
bash shell 为了保持跟 Bourne shell的兼容而包含了 expr 命令,但它同样也提供了一种更简单的方法来执行数学表达式。在 bash 中,在将一个数学运算
结果赋给某个变量时,可以用美元符和方括号($[ operation ])将数学表达式围起来。

示例:
    [devalone@devalone shell-script]$ var1=$[1 + 5]
    [devalone@devalone shell-script]$ echo $var1
    6
    [devalone@devalone shell-script]$ var2=$[$var1 * 2]
    [devalone@devalone shell-script]$ echo $var2
    12

用方括号执行 shell 数学运算比用 expr 命令方便很多。这种技术也适用于 shell 脚本。

示例:
    [devalone@devalone shell-script]$ cat test7.sh
    #!/bin/bash
    var1=100
    var2=50
    var3=45
    var4=$[$var1 * ($var2 - $var3)]
    echo The final result is $var4

运行:
    [devalone@devalone shell-script]$ chmod a+x test7.sh
    [devalone@devalone shell-script]$ test7.sh
    The final result is 500

在使用方括号来计算公式时,不用担心 shell 会误解乘号或其他符号。shell 知道它不是通配符,因为它在方括号内。

在 bash shell脚本中进行算术运算会有一个主要的限制,bash shell数学运算符只支持整数运算。若要进行任何实际的数学计算,这是一个巨大的限制。

示例:

    [devalone@devalone shell-script]$ cat test8.sh
    #!/bin/bash
    var1=100
    var2=45
    var3=$[$var1 / $var2]
    echo The final result is $var3

运行:
    [devalone@devalone shell-script]$ test8.sh
    The final result is 2

    
    NOTE:
    -------------------------------------------------------------------------------------------------------------------------------------
    z shell(zsh)提供了完整的浮点数算术操作。如果需要在shell脚本中进行浮点数运算,可以考虑看看z shell
    
    
1.7.3 浮点解决方案
-----------------------------------------------------------------------------------------------------------------------------------------
有几种解决方案能够克服 bash 中数学运算的整数限制。最常见的方案是用内建的 bash 计算器,叫作bc。


■ bc 的基本用法
-----------------------------------------------------------------------------------------------------------------------------------------
bash 计算器实际上是一种编程语言,它允许在命令行中输入浮点表达式,然后解释并计算该表达式,最后返回结果。bash 计算器能够识别:

    □ 数字(整数和浮点数)
    □ 变量(简单变量和数组)
    □ 注释(以#或C语言中的/* */开始的行)
    □ 表达式
    □ 编程语句(例如if-then语句)
    □ 函数

可以在 shell 提示符下通过 bc 命令访问 bash 计算器:

    [devalone@devalone shell-script]$ bc
    bc 1.06.95
    Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
    This is free software with ABSOLUTELY NO WARRANTY.
    For details type `warranty'.
    12 * 5.4
    64.8
    3.156 * (3 + 5)
    25.248
    quit

要退出 bash 计算器,必须输入 quit。

浮点运算是由内建变量 scale 控制的。必须将这个值设置为希望在计算结果中保留的小数位数,否则无法得到期望的结果。

示例:

    [devalone@devalone shell-script]$ bc -q
    3.44 / 5
    0
    scale=4
    3.44/5
    .6880
    quit

scale 变量的默认值是 0。在 scale 值被设置前,bash 计算器的计算结果不包含小数位。在将其值设置成 4 后,bash 计算器显示的结果包含四位小数。
-q 命令行选项可以不显示 bash 计算器冗长的欢迎信息。

除了普通数字,bash 计算器还能支持变量。

示例:
    [devalone@devalone shell-script]$ bc -q
    var1=10
    var1 * 4
    40
    var2=var1 / 5
    print var2
    2
    quit

变量一旦被定义,就可以在整个 bash 计算器会话中使用该变量了。print 语句允许打印变量和数字。

 

■ 在脚本中使用 bc
-----------------------------------------------------------------------------------------------------------------------------------------
可以用命令替换运行 bc 命令,并将输出赋给一个变量。基本格式如下:

    variable=$(echo "options; expression" | bc)

第一部分 options 允许设置变量。如果需要不止一个变量,可以用分号将其分开。expression 参数定义了通过 bc 执行的数学表达式。

示例:

    [devalone@devalone shell-script]$ cat test9.sh
    #!/bin/bash
    var1=$(echo "scale=4; 3.44/5" | bc)
    echo The answer is $var1

运行:
    [devalone@devalone shell-script]$ test9.sh
    The answer is .6880

示例:
    [devalone@devalone shell-script]$ cat test10.sh
    #!/bin/bash
    var1=100
    var2=45
    var3=$(echo "scale=4; $var1/$var2" | bc)
    echo The answer for this is $var3

运行:
    [devalone@devalone shell-script]$ test10.sh
    The answer for this is 2.2222

当然,一旦变量被赋值,那个变量也可以用于其他运算。

示例:
[devalone@devalone shell-script]$ cat test11.sh
#!/bin/bash
var1=20
var2=3.14159
var3=$(echo "scale=4; $var1 * $var1" | bc)
var4=$(echo "scale=4; $var3 * $var2" | bc)
echo The final result is $var4

输出:
    [devalone@devalone shell-script]$ test11.sh
    The final result is 1256.63600

这个方法适用于较短的运算,但有时会涉及更多的数字。如果需要进行大量运算,在一个命令行中列出多个表达式就会有点麻烦。

有一个方法可以解决这个问题。bc 命令能识别输入重定向,允许将一个文件重定向到 bc 命令来处理。但这同样会叫人头疼,因为还得将表达式存放到
文件中。


最好的办法是使用内联输入重定向,它允许直接在命令行中重定向数据。在 shell 脚本中,可以将输出赋给一个变量。
如下形式:

    variable=$(bc << EOF
    options
    statements
    expressions
    EOF
    )

EOF 文本字符串标识了内联重定向数据的起止。记住,仍然需要命令替换符号将 bc 命令的输出赋给变量。

现在可以将所有 bash 计算器涉及的部分都放到同一个脚本文件的不同行。

示例:
    
    [devalone@devalone shell-script]$ cat test12.sh
    #!/bin/bash
    var1=10.46
    var2=43.67
    var3=33.2
    var4=71

    var5=$(bc <<EOF
    scale=4
    al=($var1 * $var2)
    b1=($var3 * $var4)
    a1+b1
    EOF
    )

    echo The final answer for this mess is $var5

运行:
    [devalone@devalone shell-script]$ test12.sh
    The final answer for this mess is 2357.2


将选项和表达式放在脚本的不同行中可以让处理过程变得更清晰,提高易读性。EOF 字符串标识了重定向给 bc 命令的数据的起止。当然,必须用命令替换符号
标识出用来给变量赋值的命令。

还会注意到,在这个例子中,可以在 bash 计算器中赋值给变量。这一点很重要:在 bash 计算器中创建的变量只在 bash 计算器中有效,不能在 shell
脚本中使用。


1.8 退出脚本
-----------------------------------------------------------------------------------------------------------------------------------------
shell 中运行的每个命令都使用退出状态码(exit status)告诉 shell 它已经运行完毕。退出状态码是一个 0~255 的整数值,在命令结束运行时由命令
传给 shell。可以捕获这个值并在脚本中使用。


1.8.1 查看退出状态码
-----------------------------------------------------------------------------------------------------------------------------------------
Linux 提供了一个专门的变量 $? 来保存上个已执行命令的退出状态码。对于需要进行检查的命令,必须在其运行完毕后立刻查看或使用 $? 变量。它的值
会变成由 shell 所执行的最后一条命令的退出状态码。

示例:
    [devalone@devalone shell-script]$ who
    devalone pts/0        2018-07-05 11:05 (192.168.1.101)
    [devalone@devalone shell-script]$ echo $?
    0

一个成功结束的命令的退出状态码是 0。如果一个命令结束时有错误,退出状态码就是一个正数值。

示例:
    [devalone@devalone shell-script]$ zzzz
    bash: zzzz: 未找到命令...
    [devalone@devalone shell-script]$ echo $?
    127

无效命令会返回一个退出状态码 127。Linux 错误退出状态码没有什么标准可循,但有一些可用的参考,如下表:

        Linux 退出状态码
        +-----------+--------------------------------
        | 状态码    | 描 述
        +-----------+--------------------------------
        | 0            | 命令成功结束
        +-----------+--------------------------------
        | 1            | 一般性未知错误
        +-----------+--------------------------------
        | 2            | 不适合的shell命令
        +-----------+--------------------------------
        | 126        | 命令不可执行
        +-----------+--------------------------------
        | 127        | 没找到命令
        +-----------+--------------------------------
        | 128        | 无效的退出参数
        +-----------+--------------------------------
        | 128+x        | 与Linux信号x相关的严重错误
        +-----------+--------------------------------
        | 130        | 通过Ctrl+C终止的命令
        +-----------+--------------------------------
        | 255        | 正常范围之外的退出状态码        
        +-----------+--------------------------------
        
        
退出状态码 126 表明用户没有执行命令的正确权限:

    [devalone@devalone shell-script]$ testfile
    -bash: ./testfile: Permission denied
    [devalone@devalone shell-script]$ echo $?
    126

另一个会碰到的常见错误是给某个命令提供了无效参数:

    [devalone@devalone shell-script]$ date %t
    date: 无效的日期"%t"
    [devalone@devalone shell-script]$ echo $?
    1

    
1.8.2 exit 命令
-----------------------------------------------------------------------------------------------------------------------------------------
默认情况下,shell脚本会以脚本中的最后一个命令的退出状态码退出。可以改变这种默认行为,返回自己的退出状态码。exit 命令允许在脚本结束时指定
一个退出状态码。

示例:
    [devalone@devalone shell-script]$ cat test13.sh
    #!/bin/bash
    # testing the exit status

    var1=10
    var2=30
    var3=$[$var1 + $var2]
    echo The answer is $var3
    exit 5
    
运行:
    [devalone@devalone shell-script]$ test13.sh
    The answer is 40
    [devalone@devalone shell-script]$ echo $?
    5

    
也可以在exit命令的参数中使用变量:

    [devalone@devalone shell-script]$ cat test14.sh
    #!/bin/bash
    # testing the exit status
    var1=10
    var2=30
    var3=$[$var1 + $var2]
    exit $var3

运行:
    [devalone@devalone shell-script]$ test14.sh
    [devalone@devalone shell-script]$ echo $?
    40

要注意这个功能,退出状态码最大只能 255,如果超出 255,shell 通过模运算得到这个结果。一个值的模就是被除后的余数。最终的结果是指定的数值
除以 256 后得到的余数:

示例:
    [devalone@devalone shell-script]$ cat test14b.sh
    #!/bin/bash
    # testing the exit status
    var1=10
    var2=30
    var3=$[$var1 * $var2]
    echo The value is $var3
    exit $var3

运行:
    [devalone@devalone shell-script]$ test14b.sh
    The value is 300
    [devalone@devalone shell-script]$ echo $?
    44

系列目录:

    Linux shell 脚本编程-基础篇 (一)

    Linux shell 脚本编程-基础篇 (二)

    Linux shell 脚本编程-基础篇 (三)

    Linux shell 脚本编程-基础篇 (四)

    Linux shell 脚本编程-基础篇 (五)

    Linux shell 脚本编程-基础篇 (六)

 

 

-----------------------------------------------------------------------------------------------------------------------------------------
参考:

    《Linux 命令行与 shell 脚本编程大全》 第 3 版 —— 2016.8(美)Richard Blum  Cristine Bresnahan

linux shell脚本编程学习(一)基础 1.使用多个命令 在linux中如果想要两个命令一起运行,则在中间使用分号分割开: 如下 # date ; who 则会先运行date命令打印出当前时间,在运行who命令打印出当前登陆在系统中的用户。 2.创建shell脚本 创建shell脚本需要在本文的第一行输入#!/bin/bash,“#!”后面跟着的shell代表要使用的shell,也可以指定为其他shell。只有在第一 阅读详情

相关推荐

Shell脚本编程基础及实战

本文还有配套的精品资源,点击获取 简介:标题和简介未提供具体信息,但通过标签“Shell”推测主题与Unix/Linux系统中的Shell脚本编程相关。Shell是命令行解释器,允许执行系统操作。Shell脚本用于自动化命令行任务,包含控制结构、条件语句、循环语句等。本课程深入探讨Shell编程基础,包括脚本结构、变量赋值、命令行参数处理、流程控制、文件与目录操作、管道与重...

weixin_42613017的博客 1558

修改history记录一百万行

首先,你需要修改全局配置文件,以确保所有用户的命令历史记录都被保存,并且记录行数增加到1000000行。文件,或者用户的主目录路径不符合预期。为了确保脚本的健壮性,我们可以添加一些检查和改进。你提到的脚本在某些情况下可能会报错,特别是如果用户的主目录中没有。你可以编写一个脚本来自动化这个过程,遍历所有用户的主目录并修改。为了确保每个用户的配置文件也包含这些设置,你可以在每个用户的。文件时更加健壮,并且不会因为文件不存在或不可写而报错。文件中添加相同的配置。通过以上步骤,你可以确保脚本在处理用户的。

weixin_46356409的博客 915

abrt-addon-vmcore-2.1.11-57.el7.centos.x86_64.rpm

Centos7 el7.x86_64 官方离线安装包,安装指令为 sudo rpm -ivh abrt-addon-vmcore-2.1.11-57.el7.centos.x86_64.rpm

Linux执行脚本报:invalid option错误

vim进入脚本,输入:set ff,看到 fileformat=dos ,即当前的文件格式是windows的格式。输入:set ff=unix,将dos格式转化为unix格式,然后输入:wq,退出脚本,重新执行脚本即可。

weixin_46605854的博客 2371

告别天价授权!手把手教你用TwinCAT 3.1搭建EtherCAT主站(Windows 10/11保姆级教程)

本文详细介绍了如何在Windows 10/11系统上使用TwinCAT 3.1免费搭建EtherCAT主站,帮助中小企业和个人开发者低成本实现工业自动化。从环境准备、许可证策略到安装配置和实战开发,提供保姆级教程,涵盖PLC编程、运动控制及硬件选型建议,助您轻松入门工业控制领域。

weixin_30664615的博客 363

避坑指南:Vue2中使用TinyMCE5常见问题解决方案(含PowerPaste插件异常处理)

本文针对Vue2项目中集成TinyMCE 5富文本编辑器时遇到的高频疑难问题,提供了一套深度实战解决方案。内容涵盖环境搭建、资源路径配置、图片与视频上传处理、以及替代PowerPaste插件的自定义粘贴清理方案,旨在帮助开发者有效规避常见陷阱,构建稳定可靠的内容编辑功能。

weixin_29012677的博客 156

Linux shell编程学习笔记28:脚本调试 set命令

set命令用于查看和修改 Shell 环境的运行参数,我们可以依照不同的需求来设置shell的执行方式,实现定制 Shell 脚本的运行环境。bash和zsh对set命令的支持是不同的。

Purpleendurer@优快云 2085

射频总集篇:(不断更新)

射频每一章涉及到的重点理论/设计方法 CHAPTER 1 传输线理论 输入阻抗Zin,负载阻抗ZL,驻波比ρ,反射系数 CHAPTER 2 波导 矩形波导,圆波导,同轴线 CHAPTER 3 微型带状传输线 微带线的参数设计,带状线的参数设计 CHAPTER 4 ...

jieyannn的博客 1922

Linux学习之bash基础特性

1、bash基础特性之命令历史:shell进程会在其会话中保存此用户提交执行过的命令,shell进程启动后所有当前执行过的命令都会保存在shell进程的内存中;只有用户登出时才保存到文件中。 (1)history命令 history命令用于查看已经运行过的命令 [root@hu lib]# history 1 su root 2 ls 3 cd / 4 po...

菜鸟博客 955

IoTDB时序数据库在Windows下的保姆级安装教程(含环境变量配置避坑指南)

本文提供Apache IoTDB时序数据库在Windows系统下的详细安装与配置指南。教程涵盖从Java环境检查、软件下载解压,到环境变量配置的深度避坑,并详解了服务的启动、停止、连接测试及基础数据操作,帮助物联网开发者在Windows平台快速搭建稳定的时序数据库环境。

weixin_29275257的博客 264

手把手教你用C#和LibUsbDotNet实现USB设备通信(含完整代码示例)

本文详细介绍了如何使用C#和LibUsbDotNet库实现USB设备通信,包括设备识别、连接建立、同步/异步数据读写等核心操作。通过完整的代码示例,开发者可以快速掌握USB通信的关键技术,适用于工业自动化、医疗设备等多种场景。重点讲解了数据读写优化和错误处理技巧,帮助提升通信效率和可靠性。

a3b4c5的博客 707

Linux历史命令管理以及用法

history命令管理及用法总结 命令历史:shell进程会在其会话中保存此前用户提交执行过的命令,可以用它来重复执行命令;包括关机之前的指令    ~]# history示例     定制history的功能,可通过改变环境变量的具体值来实现: 环境变量 意义 HISTSIZE shell进程可保留的命令历史的条数 HISTFILE 持久保存命令历史的文件 HISTFILE...

weixin_34138056的博客 135

61、神经科学中的分岔与双分子反应研究

本文探讨了神经科学中的分岔现象与双分子反应建模。在神经元网络中,通过分析四细胞网络的呼吸节律振荡,揭示了分岔对振荡频率和占空比的影响,并区分了单神经元与网络层面的分岔特性。在神经群体模型中,系统参数变化引发的分岔可导致振荡、混沌等动态行为转变,文中详细介绍了局部分岔、全局分岔和高余维分岔的机制,并以Jansen-Rit模型为例展示了输入水平变化下的分岔过程。在分子层面,重点介绍了MWC模型在描述配体与多位点蛋白质结合中的应用,涵盖其构象状态、平衡常数及统计因子。研究表明,分岔理论和双分子反应建模为理解神经系

yog99的博客 80

Linux shell 脚本编程-高级篇 (一)

1. 创建函数 可以将 shell 脚本代码放进函数中封装起来,这样就能在脚本中的任何地方多次使用它了。 1.1 基本的脚本函数 在开始编写较复杂的 shell 脚本时,会发现自己重复使用了部分能够执行特定任务的代码。这些代码有时很简单,比如显示一条文本消息,或者从脚本用户那里获得一个答案;有时则会比较复杂,需要作为大型处理过程中的一部分被多次使用。 在后一类情况下,在脚本中一遍又一遍地...

devalone 的专栏 9001

基于BEV(鸟瞰图)的3D检测:PointPillars与CenterPoint

基于BEV(鸟瞰图)的3D检测:PointPillars与CenterPoint​ ,人工智能,计算机视觉,大模型,AI,本文围绕基于BEV的3D检测,解析了PointPillars与CenterPoint两种算法。PointPillars用点柱特征编码网络处理点云,通过2D卷积网络提取特征,检测头为解耦头;CenterPoint将三维物体表为点,分两阶段检测,先找中心点及属性,再细化预测。两者都可借特定骨干网生成BEV特征图且基于BEV检测,但检测头设计和物体表示方式不同。

不踩坑,不知道坑有多深;不总结,踩过的坑白踩。 27万+

小红书urlscheme和Activity

本文档详细介绍了小红书App的Deeplink跳转规范,涵盖了多个功能模块的跳转协议。主要内容包括:主页各Tab(关注、发现、购买)的跳转方式;不同类型笔记(图文/视频/长笔记)的详情页跳转参数;用户相关页面(主页/绑定/资料/消息等)的跳转协议;搜索功能(输入页/结果页)的跳转方式;以及话题、标签、专辑、H5页面等特殊场景的跳转实现。文档还提供了各跳转协议所需的参数说明,包括参数类型、默认值、是否必填等详细信息,并标注了不同版本和平台的兼容性要求。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 786

Linux Shell 脚本编程基础知识篇—shell简介以及基本操作

Shell本身是一个用C语言编写的程序, 它是用户使用Linux的桥梁。Shell既是一种命令语言, 又是一种程序设计语言。所有的Linux命令都是Shell脚本语言。

weixin_55767624的博客 2723

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

【Linux】基础篇四--shell脚本编程

Linux学习4--shell脚本编程一、shell编程-变量1、shell脚本的基础知识2、shell变量二、shell编程-功能语句1、说明性语句2、常用功能性语句3、测试语句三、shell编程-分支语句1、条件语句2、多路分支语句四、shell编程-循环语句1、循环语句for的用法2、循环语句while的用法3、循环控制语句五、shell编程-函数1、shell函数调用2、函数变量作用域 一、shell编程-变量 1、shell脚本的基础知识 (1)shell脚本的本质 程序语言包括编译型语言与解释型

修成真的博客 8168

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Linux基础命令-SHELL脚本编程基础

Linux基础命令-SHELL脚本编程基础SHELL脚本编程基础一、编程基础1. 编程基础2. 程序的执行方式3. 编译和解释型语言4. 编程基本概念二、脚本基本格式1. shell脚本基础2. 创建shell脚本3. 脚本规范4. 编程基本概念5. shell脚本示例6. 脚本调试三、变量1. 变量2. bash中变量的种类a. 局部变量b. 环境变量c. 只读和位置变量3. 退出状态4. 退出...

qq_41596208的博客 1603

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Linux 编写shell 脚本基础篇

LInux shell编程基础 sh bash dash区别 执行脚本方式 变量的使用 字符串

xxx_un的博客 2271

linux-Shell 编程-Shell 脚本基础

Shell脚本是由一系列Linux命令组成的文本文件,通常用于自动化完成任务。Shell脚本可以在终端中运行,而无需逐个输入命令。Shell脚本的扩展名通常为.sh,但这不是强制性的。在Shell脚本中,变量的使用是非常灵活的。变量名必须以字母或下划线开头,不能以数字开头。定义变量引用变量在引用变量时,需要在变量名前加上# 函数体Shell脚本是Linux系统管理中不可或缺的工具。通过Shell编程,用户可以自动化处理系统任务、文件操作、网络操作等一系列功能。

Flying_Fish_roe的博客 1698

Linux基础_SHELL脚本编程基础

讲师_@王晓春 本章内容▼编程基础▼shell脚本基础▷创建shell脚本▷脚本的基本结构▷变量1. Shell中变量命名法则:2. bash中变量的种类局部变量环境变量位置变量退出状态3. 算术运算赋值逻辑运算4. test命令bash的数值测试bash的文件测试54. 使用read命令来接受输入6. 条件选择 if 语句7. 条件判断:case语句▼bash的配置文件▷编辑配置文件生效1. B...

Not Found 404 3948

Linux Shell 脚本编程基础知识篇—shell 运算命令详解

各位好,我是练小杰,本文继续Linux shell脚本编程的基础知识内容,接着讲算术运算命令的详细操作,主要是led命令,read命令,be命令,expr命令等。

weixin_55767624的博客 1738

Linux之Shell脚本篇(一)

Shell编程是将Linux命令按逻辑存储在脚本文件中,通过/bin/bash等解释器执行,实现任务自动化以提高运维效率。脚本文件需以#!/bin/bash开头,添加执行权限后运行,示例包括打印"Hello World"和自动安装Nginx。Shell变量分为系统变量、环境变量和用户变量,用于简化数值调用和管理。系统变量如$0、$1等处理脚本参数,环境变量存储全局配置,用户变量为临时使用。开发规范包括变量命名规则、注释说明和逻辑顺序。进阶应用涉及条件判断(if语句)和参数验证,如Ngin

2401_83150173的博客 814

shell脚本编程基础

Linux的Shell种类众多,常见的有:/bin/sh /bin/bash /sbin/nologin /bin/dash /bin/tcsh /bin/csh  从程序员的角度来看, Shell本身是一种用C语言编写的程序,从用户的角度来看,Shell是用户与Linux操作系统沟通的桥梁。用户既可以输入命令执行,又可以利用 Shell脚本编程,完成更加复杂的操作。在Linux GUI日益完善的今

Wyxtnbp的博客 2730

linux之基础shell脚本编程1 基础变量赋值

linux之基础shell脚本编程1 基础变量赋值

第九系艾文 3036
上一篇: 走进 Linux shell (三)
下一篇: Linux shell 脚本编程-基础篇 (二)
devalone
博客等级 码龄17年 108粉丝 80原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值