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

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

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


2. 使用结构化命令


许多程序要求对 shell 脚本中的命令施加一些逻辑流程控制。有一类命令会根据条件使脚本跳过某些命令。这样的命令通常称为结构化命令(structured command)。结构化命令允许改变程序执行的顺序。

 

2.1 使用 if-then 语句
-----------------------------------------------------------------------------------------------------------------------------------------
最基本的结构化命令就是 if-then 语句。if-then语句有如下格式:

    if command
    then
        commands
    fi

在其他编程语言中,if 语句之后的对象是一个等式,这个等式的求值结果为 TRUE 或 FALSE。但 bash shell 的 if 语句并不是这么做的。bash shell 的
if 语句会运行 if 后面的那个命令。如果该命令的退出状态码是 0 (该命令成功运行),位于 then 部分的命令就会被执行。如果该命令的退出状态码是
其他值, then 部分的命令就不会被执行,bash shell 会继续执行脚本中的下一个命令。fi 语句用来表示 if-then 语句到此结束。

示例:
    [devalone@devalone 12]$ cat test1.sh
    #!/bin/bash
    # testing the if statement
    if pwd
    then
        echo "It worked"
    fi

这个脚本在 if 行采用了 pwd 命令。如果命令成功结束,echo 语句就会显示该文本字符串。

运行:
    [devalone@devalone 12]$ test1.sh
    /home/devalone/study/shell-script
    It worked
    [devalone@devalone 12]$

shell 执行了 if 行中的 pwd 命令。由于退出状态码是 0,它就又执行了 then 部分的 echo语句。

示例:
[devalone@devalone 12]$ cat test2.sh
#!/bin/bash
# testing a bad command

if IamNotaCommand
then
    echo "It worked"
fi
echo "We are outside the if statement"

运行:
    [devalone@devalone 12]$ test2.sh
    ./test2.sh:行4: IamNotaCommand: 未找到命令
    We are outside the if statement

在这个例子中,if 语句行故意放了一个不能工作的命令。由于这是个错误的命令,所以它会产生一个非零的退出状态码,且 bash shell 会跳过 then 部分
的 echo 语句。还要注意,运行if语句中的那个错误命令所生成的错误消息依然会显示在脚本的输出中。

    NOTE:
    -------------------------------------------------------------------------------------------------------------------------------------
    可能在有些脚本中看到过 if-then 语句的另一种形式:
    
        if command; then
            commands
        fi
        
    通过把分号放在待求值的命令尾部,就可以将 then 语句放在同一行上了,这样看起来更像其他编程语言中的 if-then 语句。
    
在 then 部分,可以使用不止一条命令。可以像在脚本中的其他地方一样在这里列出多条命令。bash shell 会将这些命令当成一个块,如果 if 语句行的
命令的退出状态值为 0,所有的命令都会被执行;如果 if 语句行的命令的退出状态不为 0,所有的命令都会被跳过。

[devalone@devalone 12]$ cat test3.sh
#!/bin/bash
# testing multiple commands in the then section
#
Devalone=devalone
#
if grep $Devalone /etc/passwd; then
    echo "This is my first command"
    echo "This is my second command"
    echo "I can even put in other commands besides echo:"
    ls -al /home/$Devalone/.b*
fi

if 语句行使用 grep 命令在 /etc/passwd 文件中查找某个用户名当前是否在系统上使用。如果有用户使用了那个登录名,脚本会显示一些文本信息并列出
该用户 HOME 目录的 bash文件。

运行:
    [devalone@devalone 12]$ test3.sh
    devalone:x:1000:1000:MichaelY.:/home/devalone:/bin/bash
    This is my first command
    This is my second command
    I can even put in other commands besides echo:
    -rw-------. 1 devalone devalone 16190 7月   4 20:31 /home/devalone/.bash_history
    -rw-r--r--. 1 devalone devalone    18 5月  17 2016 /home/devalone/.bash_logout
    -rw-r--r--. 1 devalone devalone   425 2月  26 15:24 /home/devalone/.bash_profile
    -rw-r--r--. 1 devalone devalone   301 12月 17 2017 /home/devalone/.bashrc

 

2.2 if-then-else 语句
-----------------------------------------------------------------------------------------------------------------------------------------
在 if-then 语句中,不管命令是否成功执行,都只有一种选择。如果命令返回一个非零退出状态码,bash shell 会继续执行脚本中的下一条命令。在这种
情况下,如果能够执行另一组命令就好了。这正是 if-then-else 语句的作用。

if-then-else 语句在语句中提供了另外一组命令:

    if command
    then
        commands
    else
        commands
    fi

当 if 语句中的命令返回退出状态码 0 时,then 部分中的命令会被执行,这跟普通的 if-then 语句一样。当 if 语句中的命令返回非零退出状态码时,
bash shell 会执行 else 部分中的命令。

示例:

    [devalone@devalone 12]$ cat test4.sh
    #!/bin/bash
    # testing multiple commands in the then section
    #
    testuser=NoSuchUser
    #
    if grep $testuser /etc/passwd; then
        echo "The bash files for user $testuser"
        ls -al /home/$testuser/.b*
        echo
    else
        echo "The user $testuser does not exist on this system"
        echo
    fi

运行:

    [devalone@devalone 12]$ test4.sh
    The user NoSuchUser does not exist on this system

跟 then 部分一样,else 部分可以包含多条命令。fi 语句说明 else 部分结束了。


2.3 嵌套 if
-----------------------------------------------------------------------------------------------------------------------------------------
要检查脚本代码中的多种条件。对此,可以使用嵌套的 if-then 语句。

要检查 /etc/passwd 文件中是否存在某个用户名以及该用户的目录是否尚在,可以使用嵌套的 if-then 语句。嵌套的 if-then 语句位于主 if-then-else
语句的 else 代码块中。

示例:

    [devalone@devalone 12]$ ll -d /home/test
    drwx------. 3 test test 4096 7月   4 16:05 /home/test

    [devalone@devalone 12]$ cat test5.sh
    #!/bin/bash
    # Testing nested ifs
    #
    testuser=test
    #
    if grep $testuser /etc/passwd
    then
        echo "The user $testuser exists on this system"
    else
        echo "The user $testuser does not exist on this system"
        if ls -d /home/$testuser/
        then
            echo "However, $testuser has a directory"
        fi
    fi

运行:
    [devalone@devalone 12]$ test5.sh
    The user test does not exist on this system
    /home/test/
    However, test has a directory


脚本准确地发现,尽管登录名已经从 /etc/passwd 中删除了,但是该用户的目录仍然存在。在脚本中使用这种嵌套 if-then 语句的问题在于代码不易阅读,
很难理清逻辑流程。

可以使用 else 部分的另一种形式:elif。这样就不用再书写多个 if-then 语句了。elif 使用另一个 if-then 语句延续 else 部分。格式如下:

    if command1
    then
        commands
    elif command2
    then
        more commands
    fi

elif 语句行提供了另一个要测试的命令,这类似于原始的 if 语句行。如果 elif 后命令的退出状态码是 0,则 bash 会执行第二个 then 语句部分的命令。
使用这种嵌套方法,代码更清晰,逻辑更易懂。

示例:

    [devalone@devalone 12]$ cat test5-1.sh
    #!/bin/bash
    # Testing nested ifs - use elif
    #
    testuser=test
    #
    if grep $testuser /etc/passwd
    then
        echo "The user $testuser exists on this system"
    elif ls -d /home/$testuser/
    then
        echo "The user $testuser does not exist on this system"
        echo "However, $testuser has a directory"
    fi

运行:
    [devalone@devalone 12]$ test5-1.sh
    /home/test/
    The user test does not exist on this system
    However, test has a directory

可以更进一步,让脚本检查拥有目录的不存在用户以及没有拥有目录的不存在用户。这可以通过在嵌套 elif 中加入一个 else 语句来实现。

示例:

    [devalone@devalone 12]$ cat test5-2.sh
    #!/bin/bash
    # Testing nested ifs - use elif
    #
    testuser=test
    #
    if grep $testuser /etc/passwd
    then
        echo "The user $testuser exists on this system"
    elif ls -d /home/$testuser/
    then
        echo "The user $testuser does not exist on this system"
        echo "However, $testuser has a directory"
    else
        echo "The use $testuser does not exist on this system"
        echo "And, $testuser does not have a directory"
    fi

运行:

    [devalone@devalone 12]$ test5-2.sh
    /home/test/
    The user test does not exist on this system
    However, test has a directory

运行:
    [devalone@devalone 12]$ sudo rm -rf /home/test
    
    [devalone@devalone 12]$ test5-2.sh
    ls: 无法访问'/home/test/': No such file or directory
    The use test does not exist on this system
    And, test does not have a directory
    
在 /home/test 目录被删除之前,这个测试脚本执行的是 elif 语句,返回零值的退出状态。因此 elif 的 then 代码块中的语句得以执行。删除了
/home/test 目录之后,elif 语句返回的是非零值的退出状态。这使得 elif 块中的 else 代码块得以执行。    


    NOTE:
    -------------------------------------------------------------------------------------------------------------------------------------
    记住,在 elif 语句中,紧跟其后的 else 语句属于 elif 代码块。它们并不属于之前的 if-then 代码块。

可以继续将多个 elif 语句串起来,形成一个大的 if-then-elif 嵌套组合:

    if command1
    then
        command set 1
    elif command2
    then
        command set 2
    elif command3
    then
        command set 3
    elif command4
    then
        command set 4
    fi

每块命令都会根据命令是否会返回退出状态码 0 来执行。bash shell 会依次执行 if语句,只有第一个返回退出状态码 0 的语句中的 then 部分会被执行。

 

2.4 test 命令
-----------------------------------------------------------------------------------------------------------------------------------------
到目前为止,在 if 语句中看到的都是普通 shell命令。if-then 语句是否能测试命令退出状态码之外的条件。答案是不能。

但在 bash shell 中有个好用的工具可以帮通过 if-then 语句测试其他条件。

test 命令提供了在 if-then 语句中测试不同条件的途径。如果 test 命令中列出的条件成立,test 命令就会退出并返回退出状态码 0。这样 if-then 语句
就与其他编程语言中的 if-then语句以类似的方式工作了。如果条件不成立,test命令就会退出并返回非零的退出状态码,这使得if-then语句不会再被执行。

test命令的格式:

    test condition

condition 是 test 命令要测试的一系列参数和值。当用在 if-then 语句中时,test 命令看起来是这样的。

    if test condition
    then
        commands
    fi

如果不写 test 命令的 condition 部分,它会以非零的退出状态码退出,并执行 else 语句块。

示例:
    [devalone@devalone 12]$ cat test6.sh
    #!/bin/bash
    # Testing the test command
    #
    if test
    then
        echo "No expression returns a True"
    else
        echo "No expression resturn a False"
    fi

运行:
    [devalone@devalone 12]$ test6.sh
    No expression resturn a False

当加入一个条件时,test 命令会测试该条件。例如,可以使用 test 命令确定变量中是否有内容。这只需要一个简单的条件表达式。

    [devalone@devalone 12]$ cat test6-1.sh
    #!/bin/bash
    # Testing the test command
    #
    my_variable="Full"
    #
    if test $my_variable
    then
        echo "The $my_variable expression returns a True"
    else
        echo "The $my_variable expression resturn a False"
    fi
    
运行:

    [devalone@devalone 12]$ test6-1.sh
    The Full expression returns a True

变量 my_variable 中包含有内容(Full),因此当 test 命令测试条件时,返回的退出状态为 0。这使得 then 语句块中的语句得以执行。

如果该变量中没有包含内容,就会出现相反的情况:

    [devalone@devalone 12]$ cat test6-2.sh
    #!/bin/bash
    # Testing the test command
    #
    my_variable=""
    #
    if test $my_variable
    then
        echo "The $my_variable expression returns a True"
    else
        echo "The $my_variable expression resturn a False"
    fi
    [devalone@devalone 12]$ cat test6-2.sh
    #!/bin/bash
    # Testing the test command
    #
    my_variable=""
    #
    if test $my_variable
    then
        echo "The $my_variable expression returns a True"
    else
        echo "The $my_variable expression resturn a False"
    fi

运行:

    [devalone@devalone 12]$ test6-2.sh
    The  expression resturn a False


bash shell提供了另一种条件测试方法,无需在 if-then 语句中声明 test 命令:

    if [ condition ]
    then
        commands
    fi

方括号定义了测试条件。注意,第一个方括号之后和第二个方括号之前必须加上一个空格,否则会报错。

test 命令可以判断三类条件:

    □ 数值比较
    □ 字符串比较
    □ 文件比较


2.4.1 数值比较
-----------------------------------------------------------------------------------------------------------------------------------------
使用 test 命令最常见的情形是对两个数值进行比较。下表列出了测试两个值时可用的条件参数。

    test 命令的数值比较功能
    +---------------+------------------------------------------------------------------------
    | 比 较            | 描 述
    +---------------+------------------------------------------------------------------------
    | n1 -eq n2        | 检查n1是否与n2相等
    +---------------+------------------------------------------------------------------------
    | n1 -ge n2        | 检查n1是否大于或等于n2
    +---------------+------------------------------------------------------------------------
    | n1 -gt n2        | 检查n1是否大于n2
    +---------------+------------------------------------------------------------------------
    | n1 -le n2        | 检查n1是否小于或等于n2
    +---------------+------------------------------------------------------------------------
    | n1 -lt n2        | 检查n1是否小于n2
    +---------------+------------------------------------------------------------------------
    | n1 -ne n2        | 检查n1是否不等于n2
    +---------------+------------------------------------------------------------------------

数值条件测试可以用在数字和变量上:

    [devalone@devalone 12]$ cat numeric_test.sh
    #!/bin/bash
    # Using numeric test evaluations
    #
    value1=10
    value2=11
    #
    if [ $value1 -gt 5 ]
    then
        echo "The test value $value1 is greater than 5"
    fi
    #
    if [ $value1 -eq $value2 ]
    then
        echo "The values are equal"
    else
        echo "The values are different"
    fi
    #

运行:
    [devalone@devalone 12]$ numeric_test.sh
    The test value 10 is greater than 5
    The values are different

但是涉及浮点值时,数值条件测试会有一个限制。

    [devalone@devalone 12]$ cat floating_poing_test.sh
    #!/bin/bash
    # Using floating point numbers in test evaluations
    #
    value1=5.555
    #
    echo "The test value is $value1"
    #
    if [ $value1 -gt 5 ]
    then
        echo "The test value $value1 is greater than 5"
    fi
    #

运行:
    
    [devalone@devalone 12]$ floating_poing_test.sh
    The test value is 5.555
    ./floating_poing_test.sh: 第 8 行:[: 5.555: 需要整数表达式

变量 value1 中存储的是浮点值。接着,脚本对这个值进行了测试。显然这里出错了。

记住,bash shell 只能处理整数。如果只是要通过 echo 语句来显示这个结果,那没问题。但在基于数字的函数中就不行了,例如数值测试条件。最后
一行就说明不能在 test 命令中使用浮点值。


2.4.2 字符串比较
-----------------------------------------------------------------------------------------------------------------------------------------
条件测试还允许比较字符串值。下表列出可用的字符串比较功能。

    字符串比较测试
    +---------------+------------------------------------------------------------------------
    | 比 较            | 描 述
    +---------------+------------------------------------------------------------------------
    | str1 = str2    | 检查str1是否和str2相同
    +---------------+------------------------------------------------------------------------
    | str1 != str2    | 检查str1是否和str2不同
    +---------------+------------------------------------------------------------------------
    | str1 < str2    | 检查str1是否比str2小
    +---------------+------------------------------------------------------------------------
    | str1 > str2    | 检查str1是否比str2大
    +---------------+------------------------------------------------------------------------
    | -n str1        | 检查str1的长度是否非0
    +---------------+------------------------------------------------------------------------
    | -z str1        | 检查str1的长度是否为0
    +---------------+------------------------------------------------------------------------

● 字符串相等性
-----------------------------------------------------------------------------------------------------------------------------------------
很容易看出两个字符串值是否相同:

示例:

    [devalone@devalone 12]$ cat test7.sh
    #!/bin/bash
    #
    # Testing string equality
    #
    testuser=devalone
    #
    if [ $USER = $testuser ]
    then
        echo "Welcome $testuser"
    fi

运行:
    [devalone@devalone 12]$ test7.sh
    Welcome devalone


字符串不等条件也可以判断两个字符串是否有相同的值。

示例:
    [devalone@devalone 12]$ cat test8.sh
    #!/bin/bash
    # Testing string equality
    testuser=baduser
    #
    if [ $USER != $testuser ]
    then
        echo "This is not $testuser"
    else
        echo "Welcome $testuser"
    fi

运行:
    [devalone@devalone 12]$ test8.sh
    This is not baduser

在比较字符串的相等性时,比较测试会将所有的标点和大小写情况都考虑在内。


● 字符串顺序
-----------------------------------------------------------------------------------------------------------------------------------------
要测试一个字符串是否比另一个字符串大就是麻烦的开始。当要开始使用测试条件的大于或小于功能时,就会出现两个经常困扰 shell 程序员的问题:

    □ 大于号和小于号必须转义,否则shell会把它们当作重定向符号,把字符串值当作文件名;
    □ 大于和小于顺序和 sort 命令所采用的不同

示例:

    [devalone@devalone 12]$ cat badtest.sh
    #!/bin/bash
    # mis-using string comparisons
    #
    val1=baseball
    val2=hockey
    #
    if [ $val1 > $val2 ]
    then
    echo "$val1 is greater than $val2"
    else
    echo "$val1 is less than $val2"
    fi

运行:
    [devalone@devalone 12]$ badtest.sh
    baseball is greater than hockey

    [devalone@devalone 12]$ ll hockey
    -rw-rw-r--. 1 devalone devalone 0 7月   5 17:17 hockey

这个脚本中只用了大于号,没有出现错误,但结果是错的。脚本把大于号解释成了输出重定向。因此,它创建了一个名为 hockey 的文件。由于重定向的
顺利完成,test 命令返回了退出状态码 0,if 语句便以为所有命令都成功结束了。

要解决这个问题,就需要正确转义大于号:

    [devalone@devalone 12]$ cat test9.sh
    #!/bin/bash
    # mis-using string comparisons
    #
    value1=baseball
    value2=hockey
    #
    if [ $value1 \> $value2 ]
    then
        echo "$value1 is greater than $value2"
    else
        echo "$value1 is less than $value2"
    fi

运行:
    [devalone@devalone 12]$ test9.sh
    baseball is less than hockey

第二个问题更细微,除非经常处理大小写字母,否则几乎遇不到。sort 命令处理大写字母的方法刚好跟 test 命令相反:

    [devalone@devalone 12]$ cat test9b.sh
    #!/bin/bash
    # testing string sort order
    #
    value1=Testing
    value2=testing
    #
    if [ $value1 \> $value2 ]
    then
        echo "$value1 is greater than $value2"
    else
        echo "$value1 is less than $value2"
    fi

运行:
    [devalone@devalone 12]$ test9b.sh
    Testing is less than testing

    [devalone@devalone 12]$ sort testfile
    testing
    Testing

在比较测试中,大写字母被认为是小于小写字母的。但 sort 命令恰好相反。当将同样的字符串放进文件中并用 sort 命令排序时,小写字母会先出现。这
是由各个命令使用的排序技术不同造成的。

比较测试中使用的是标准的 ASCII 顺序,根据每个字符的 ASCII 数值来决定排序结果。sort 命令使用的是系统的本地化语言设置中定义的排序顺序。对于
英语,本地化设置指定了在排序顺序中小写字母出现在大写字母前。


    NOTE:
    -------------------------------------------------------------------------------------------------------------------------------------
    test 命令和测试表达式使用标准的数学比较符号来表示字符串比较,而用文本代码来表示数值比较。这个细微的特性被很多程序员理解反了。如果对
    数值使用了数学运算符号,shell 会将它们当成字符串值,可能无法得到正确的结果。
    

● 字符串大小
-----------------------------------------------------------------------------------------------------------------------------------------
-n 和 -z 可以检查一个变量是否含有数据。

    [devalone@devalone 12]$ cat test10.sh
    #!/bin/bash
    # testing string length
    val1=testing
    val2=''
    #
    if [ -n val1 ]
    then
        echo "The string '$val1' is not empty"
    else
        echo "The string '$val1' is empty"
    fi
    #
    if [ -z $val2 ]
    then
        echo "The string '$val2' is empty"
    else
        echo "The string '$val2' is not empty"
    fi
    #
    if [ -z $val3 ]
    then
        echo "The string '$val3' is empty"
    else
        echo "The string '$val3' is not empty"
    fi

运行:

    [devalone@devalone 12]$ test10.sh
    The string 'testing' is not empty
    The string '' is empty
    The string '' is empty


    NOTE:
    -------------------------------------------------------------------------------------------------------------------------------------
    空的和未初始化的变量会对 shell 脚本测试造成灾难性的影响。如果不是很确定一个变量的内容,最好在将其用于数值或字符串比较之前先通过 -n 或
    -z 来测试一下变量是否含有值。


2.4.3 文件比较
-----------------------------------------------------------------------------------------------------------------------------------------
文件比较很有可能是 shell 编程中最为强大、也是用得最多的比较形式。它允许测试 Linux 文件系统上文件和目录的状态。

    test 命令的文件比较功能
    +-------------------+--------------------------------------------------------------------
    | 比 较                | 描 述
    +-------------------+--------------------------------------------------------------------
    | -d file            | 检查file是否存在并是一个目录
    +-------------------+--------------------------------------------------------------------
    | -e file            | 检查file是否存在
    +-------------------+--------------------------------------------------------------------
    | -f file            | 检查file是否存在并是一个文件
    +-------------------+--------------------------------------------------------------------
    | -h file            | 检查 file exists and is a symbolic link (same as -L)
    +-------------------+---------------------------------------------------------------------
    | -r file            | 检查file是否存在并可读
    +-------------------+--------------------------------------------------------------------
    | -s file            | 检查file是否存在并非空
    +-------------------+--------------------------------------------------------------------
    | -w file            | 检查file是否存在并可写
    +-------------------+--------------------------------------------------------------------
    | -x file            | 检查file是否存在并可执行
    +-------------------+--------------------------------------------------------------------
    | -O file            | 检查file是否存在并属当前用户所有
    +-------------------+--------------------------------------------------------------------
    | -G file            | 检查file是否存在并且默认组与当前用户相同
    +-------------------+--------------------------------------------------------------------
    | file1 -nt file2    | 检查file1是否比file2新
    +-------------------+--------------------------------------------------------------------
    | file1 -ot file2    | 检查file1是否比file2旧
    +-------------------+--------------------------------------------------------------------

这些测试条件使能够在 shell 脚本中检查文件系统中的文件。它们经常出现在需要进行文件访问的脚本中。

Except  for  -h  and -L, all FILE-related tests dereference symbolic links.  Beware that parentheses need to be escaped (e.g., by
backslashes) for shells.  INTEGER may also be -l STRING, which evaluates to the length of STRING.

 


● 检查目录
-----------------------------------------------------------------------------------------------------------------------------------------
-d 测试会检查指定的目录是否存在于系统中。如果打算将文件写入目录或是准备切换到某个目录中,先进行测试总是件好事情。

示例:
    [devalone@devalone 12]$ cat test11.sh
    #!/bin/bash
    # Look before you leap
    #
    jump_directory=/home/arthur
    #
    if [ -d $jump_directory ]
    then
        echo "The $jump_directory directory exists"
        cd $jump_directort
        ls
    else
        echo "The $jump_directory directory does not exist"
    fi
    #

运行:
    [devalone@devalone 12]$ test11.sh
    The /home/arthur directory does not exist

示例代码中使用了 -d 测试条件来检查 jump_directory 变量中的目录是否存在:若存在,就使用 cd 命令切换到该目录并列出目录中的内容;若不存在,
脚本就输出一条警告信息,然后退出。


● 检查对象是否存在
-----------------------------------------------------------------------------------------------------------------------------------------
-e 比较允许脚本代码在使用文件或目录前先检查它们是否存在。

    [devalone@devalone 12]$ cat test12.sh
    #!/bin/bash
    # Check if eithera directory or file exist
    #
    location=$HOME
    file_name="sentinel"
    #
    if [ -e $location ]
    then #Diretory does exist
        echo "OK on the $location diretory"
        echo "Now checking on the file, $file_name"
        #
        if [ -e $location/$file_name ]
        then #File does exist
            echo "OK on the filename"
            echo "Updating current date..."
            date >> $location/$file_name
            #
        else #File does not exist
            echo "File does not exist"
            echo "Noting to update"
        fi
    else #Directory does not exist
        echo "The $location directory does not exist"
        echo "Nothing to update"
    fi
    #

运行:

    [devalone@devalone 12]$ test12.sh
    OK on the /home/devalone diretory
    Now checking on the file, sentinel
    File does not exist
    Noting to update

    [devalone@devalone 12]$ touch ~/sentinel
    [devalone@devalone 12]$ test12.sh
    OK on the /home/devalone diretory
    Now checking on the file, sentinel
    OK on the filename
    Updating current date...
    [devalone@devalone 12]$

第一次检查用 -e 比较来判断用户是否有 $HOME 目录。如果有,接下来的 -e 比较会检查 sentinel 文件是否存在于 $HOME 目录中。如果不存在,shell
脚本就会提示该文件不存在,不需要进行更新。

为确保更新操作能够正常进行,我们创建了 sentinel 文件,然后重新运行这个 shell 脚本。这一次在进行条件测试时,$HOME 和 sentinel 文件都存在,
因此当前日期和时间就被追加到了文件中。

 

● 检查文件
-----------------------------------------------------------------------------------------------------------------------------------------
-e 比较可用于文件和目录。要确定指定对象为文件,必须用 -f 比较。

[devalone@devalone 12]$ cat test13.sh
#!/bin/bash
# check if either a directory or file exist
#
item_name=$HOME
echo
echo "The item being checked: $item_name"
echo
#
if [ -e $item_name ]
then #item does exist
    echo "The item, $item_name, does exist"
    echo "But is it a file ?"
    echo
    #
    if [ -f $item_name ]
    then #item is a file
        echo "Yes, $item_name is a file"
        #
    else #item is not a file
        echo "No, $item_name is not a file"
    fi
    #
else #item does not exist
    echo "The item, $item_name, does not exist"
    echo "Nothing to update"
fi

运行:
    [devalone@devalone 12]$ test13.sh

    The item being checked: /home/devalone

    The item, /home/devalone, does exist
    But is it a file ?

    No, /home/devalone is not a file

这一小段脚本进行了大量的检查!它首先使用 -e 比较测试$HOME是否存在。如果存在,继续用 -f 来测试它是不是一个文件。如果它不是文件(当然不会
是了),就会显示一条消息,表明这不是一个文件。

示例:

    [devalone@devalone 12]$ cat test13b.sh
    #!/bin/bash
    # check if either a directory or file exist
    #
    item_name=$HOME/sentinel
    echo
    echo "The item being checked: $item_name"
    echo
    #
    if [ -e $item_name ]
    then #item does exist
        echo "The item, $item_name, does exist"
        echo "But is it a file ?"
        echo
        #
        if [ -f $item_name ]
        then #item is a file
            echo "Yes, $item_name is a file"
            #
        else #item is not a file
            echo "No, $item_name is not a file"
        fi
        #
    else #item does not exist
        echo "The item, $item_name, does not exist"
        echo "Nothing to update"
    fi

运行:

    [devalone@devalone 12]$ test13b.sh

    The item being checked: /home/devalone/sentinel

    The item, /home/devalone/sentinel, does exist
    But is it a file ?

    Yes, /home/devalone/sentinel is a file

当运行这个脚本时,对 $HOME/sentinel 进行的 -f 测试所返回的退出状态码为 0,then 语句得以执行,然后输出消息。


● 检查文件是否可读
-----------------------------------------------------------------------------------------------------------------------------------------
在尝试从文件中读取数据之前,最好先测试一下文件是否可读。可以使用 -r 比较测试:

    [devalone@devalone 12]$ cat test14.sh
    #!/bin/bash
    # test if you can read a file
    pwfile=/etc/shadow
    #
    #firt, test if the file exist, and is a file
    if  [ -f $pwfile ]
    then
        # now test if you can read it
        if [ -r $pwfile ]
        then
            tail $pwfile
        else
            echo "Sorry, I am unable to read the $pwfile"
        fi
    else
        echo "Sorry, the file $pwfile does not exist"
    fi

运行:
    [devalone@devalone 12]$ test14.sh
    Sorry, I am unable to read the /etc/shadow

/etc/shadow 文件含有系统用户加密后的密码,所以它对系统上的普通用户来说是不可读的。-r 比较确定该文件不允许进行读取,因此测试失败,
bash shell执行了 if-then 语句的 else 部分。


● 检查空文件
-----------------------------------------------------------------------------------------------------------------------------------------
应该用 -s 比较来检查文件是否为空,尤其是在不想删除非空文件的时候。要留心的是,当 -s 比较成功时,说明文件中有数据。

    [devalone@devalone 12]$ cat test15.sh
    #!/bin/bash
    # testing if a file is empty
    #
    filename=$HOME/sentinel
    #
    if [ -f $filename ]
    then
        if [ -s $filename ]
        then
            echo "The $filename file exists and has data in it."
            echo "will not remove this file"
        else
            echo "The $filename file exists, but is empty"
            echo "Deleting empty file..."
        fi
    else
        echo "File, $filename, does not exist"
    fi

运行:
    [devalone@devalone 12]$ ls -l ~/sentinel
    -rw-rw-r--. 1 devalone devalone 43 7月   5 18:36 /home/devalone/sentinel

    [devalone@devalone 12]$ test15.sh
    The /home/devalone/sentinel file exists and has data in it.
    will not remove this file

    
● 检查文件是否可写
-----------------------------------------------------------------------------------------------------------------------------------------
-w 比较会判断对文件是否有可写权限:

    [devalone@devalone 12]$ cat test16.sh
    #!/bin/bash
    # check if either a file writable
    #
    item_name=$HOME/sentinel
    echo
    echo "The item being checked: $item_name"
    echo
    #
    if [ -e $item_name ]
    then #item does exist
        echo "The item, $item_name, does exist"
        echo "But is it a file ?"
        echo
        #
        if [ -f $item_name ]
        then #item is a file
            echo "Yes, $item_name is a file"
            echo "But is it writable?"
            #
            if [ -w $item_name ]
            then
                   echo "writing current time to $item_name"
                   date +%H%M >> $item_name
            else
                     echo "Unable to write to $item_name"
            fi

        else #item is not a file
            echo "No, $item_name is not a file"
        fi
        #
    else #item does not exist
        echo "The item, $item_name, does not exist"
        echo "Nothing to update"
    fi

运行:

    [devalone@devalone 12]$ test16.sh

    The item being checked: /home/devalone/sentinel

    The item, /home/devalone/sentinel, does exist
    But is it a file ?

    Yes, /home/devalone/sentinel is a file
    But is it writable?
    writing current time to /home/devalone/sentinel

    [devalone@devalone 12]$ cat  /home/devalone/sentinel
    2018年 07月 05日 星期四 18:36:25 CST
    1845

变量 item_name 被设置成 $HOME/sentinel,该文件允许用户进行写入。因此当脚本运行时,-w 测试表达式会返回退出状态码 0,然后执行 then 代码块,
将时间戳写入文件 sentinel 中。

如果使用 chmod 关闭文件 sentinel 的用户 写入权限,-w 测试表达式会返回非零的退出状态码,时间戳不会被写入文件:

    [devalone@devalone 12]$ chmod u-w ~/sentinel
    [devalone@devalone 12]$ test16.sh

    The item being checked: /home/devalone/sentinel

    The item, /home/devalone/sentinel, does exist
    But is it a file ?

    Yes, /home/devalone/sentinel is a file
    But is it writable?
    Unable to write to /home/devalone/sentinel


● 检查文件是否可以执行
-----------------------------------------------------------------------------------------------------------------------------------------
-x 比较是判断特定文件是否有执行权限。

    [devalone@devalone 12]$ cat test17.sh
    #!/bin/bash
    # testing file execution
    #
    if [ -x test16.sh ]
    then
        echo "you can run the script:"
        ./test16.sh
    else
        echo "Sorry, you are unable to execute the script"
    fi

运行:
    [devalone@devalone 12]$ test17.sh
    you can run the script:

    The item being checked: /home/devalone/sentinel

    The item, /home/devalone/sentinel, does exist
    But is it a file ?

    Yes, /home/devalone/sentinel is a file
    But is it writable?
    Unable to write to /home/devalone/sentinel

    [devalone@devalone 12]$ chmod u-x test16.sh
    [devalone@devalone 12]$ test17.sh
    Sorry, you are unable to execute the script

这段示例 shell 脚本用 -x 比较来测试是否有权限执行 test16.sh 脚本。如果有权限,它会运行这个脚本。在首次成功运行 test16.sh 脚本后,更改文件
的权限。这次,-x 比较失败了,因为已经没有 test16.sh 脚本的执行权限了。


● 检查所属关系
-----------------------------------------------------------------------------------------------------------------------------------------
-O 比较可以测试出当前用户是否是文件的属主:

    [devalone@devalone 12]$ cat test18.sh
    #/bin/bash
    # check file ownership
    #
    if [ -O /etc/passwd ]
    then
        echo "You are the owner of /etc/passwd file"
    else
        echo "You are not the owner of /etc/passwd file"
    fi

运行:

    [devalone@devalone 12]$ test18.sh
    You are not the owner of /etc/passwd file

    
    
● 检查默认属组关系
-----------------------------------------------------------------------------------------------------------------------------------------
-G 比较会检查文件的默认组,如果它匹配了用户的默认组,则测试成功。-G 比较只会检查默认组而非用户所属的所有组。

示例:

    [devalone@devalone 12]$ cat test19.sh
    #!/bin/bash
    # check file group test
    #
    if [ -G $HOME/testing ]
    then
        echo "You are in the same group as the file"
    else
        echo "The file is not owned by your group"
    fi

运行:
    [devalone@devalone 12]$ touch ~/testing
    [devalone@devalone 12]$ ll ~/testing
    -rw-rw-r--. 1 devalone devalone 0 7月   5 19:33 /home/devalone/testing

    [devalone@devalone 12]$ test19.sh
    You are in the same group as the file

    [devalone@devalone 12]$ sudo chgrp sharing ~/testing
    [devalone@devalone 12]$ ll ~/testing
    -rw-rw-r--. 1 devalone sharing 0 7月   5 19:33 /home/devalone/testing
    [devalone@devalone 12]$ test19.sh
    The file is not owned by your group


● 检查文件日期
-----------------------------------------------------------------------------------------------------------------------------------------
最后一组方法用来对两个文件的创建日期进行比较。这在编写软件安装脚本时非常有用。人们不会愿意安装一个比系统上已有文件还要旧的文件。

-nt 比较会判定一个文件是否比另一个文件新。如果文件较新,那意味着它的文件创建日期更近。
-ot 比较会判定一个文件是否比另一个文件旧。如果文件较旧,意味着它的创建日期更早。

示例:

    [devalone@devalone 12]$ cat test20.sh
    #!/bin/bash
    # testing file dates
    #
    if [ test19.sh -nt test18.sh ]
    then
        echo "The test19.sh file is newer than test18.sh"
    else
        echo "The test18.sh file is newer than test19.sh"
    fi

    if [ test17.sh -ot test19.sh ]
    then
        echo "The test17.sh file is older than test19.sh file"
    fi

运行:

    [devalone@devalone 12]$ test20.sh
    The test19.sh file is newer than test18.sh
    The test17.sh file is older than test19.sh file

用于比较文件路径是相对于运行该脚本的目录而言的。如果要检查的文件已经移走,就会出现问题。另一个问题是,这些比较都不会先检查文件是否存在。

示例:

    [devalone@devalone 12]$ cat test21.sh
    #!/bin/bash
    # testing file dates
    #
    if [ badfile1 -nt badfile2 ]
    then
    echo "The badfile1 file is newer than badfile2"
    else
    echo "The badfile2 file is newer than badfile1"
    fi

运行:

    [devalone@devalone 12]$ test21.sh
    The badfile2 file is newer than badfile1

例子演示了如果文件不存在,-nt 比较会返回一个错误的结果。在尝试使用 -nt 或 -ot 比较文件之前,必须先确认文件是存在的。


2.4.4 test 复合条件功能
-----------------------------------------------------------------------------------------------------------------------------------------

    test 命令的复合条件功能
    +-------------------+--------------------------------------------------------------------
    | 比 较                | 描 述
    +-------------------+--------------------------------------------------------------------
    | -a                | (and) 两个条件同时成立,返回 true。例如 test -r file -a -x file,则
    |                    | file 同时具有 r 不 x 权限时,才返回 true。
    +-------------------+--------------------------------------------------------------------
    | -o                | (or) 两个条件有一个成立,即返回 true。例如 test -r file -o -x file,
    |                    | 则 file 具有 r 或 x 权限时,就返回 true。
    +-------------------+--------------------------------------------------------------------
    | !                    | 取反测试,如 test !-x file, 当 file 不具有 x 权限时,返回 true
    +-------------------+--------------------------------------------------------------------

 

 

2.5 复合条件测试
-----------------------------------------------------------------------------------------------------------------------------------------
if-then 语句允许使用布尔逻辑来组合测试。有两种布尔运算符可用:

    □ [ condition1 ] && [ condition2 ]    :等同于 -a
     □ [ condition1 ] || [ condition2 ]    : 等同于 -o

第一种布尔运算使用 AND 布尔运算符来组合两个条件。要让 then 部分的命令执行,两个条件都必须满足。

    NOTE:
    -------------------------------------------------------------------------------------------------------------------------------------
    布尔逻辑是一种能够将可能的返回值简化为 TRUE 或 FALSE 的方法。

第二种布尔运算使用 OR 布尔运算符来组合两个条件。如果任意条件为 TRUE,then 部分的命令就会执行。

下例展示了AND布尔运算符的使用:

[devalone@devalone 12]$ cat test22.sh
#!/bin/bash
# testing compound comparisions
#
if [ -d $HOME ] && [ -w $HOME/testing ]
then
    echo "The file exists and you can write to it"
else
    echo "I cannot write to the file"
fi

运行:
    [devalone@devalone 12]$ test22.sh
    The file exists and you can write to it

    [devalone@devalone 12]$ rm ~/testing
    [devalone@devalone 12]$ test22.sh
    I cannot write to the file


2.6 if-then 的高级特性
-----------------------------------------------------------------------------------------------------------------------------------------
bash shell 提供了两项可在 if-then 语句中使用的高级特性:
    
    □ 用于数学表达式的双括号
    □ 用于高级字符串处理功能的双方括号
    
    
2.6.1 使用双括号 (())
-----------------------------------------------------------------------------------------------------------------------------------------
双括号命令允许在比较过程中使用高级数学表达式。test 命令只能在比较中使用简单的算术操作。双括号命令提供了更多的数学符号,这些符号对于用过
其他编程语言的程序员而言并不陌生。双括号命令的格式如下:

    (( expression ))

expression 可以是任意的数学赋值或比较表达式。除了 test 命令使用的标准数学运算符,下表列出了双括号命令中会用到的其他运算符。

    双括号命令符号
    +-----------+---------------------------------------------------------
    | 符 号        | 描 述
    +-----------+---------------------------------------------------------
    | val++        | 后增
    +-----------+---------------------------------------------------------
    | val--        | 后减
    +-----------+---------------------------------------------------------
    | ++val        | 先增
    +-----------+---------------------------------------------------------
    | --val        | 先减
    +-----------+---------------------------------------------------------
    | !            | 逻辑求反
    +-----------+---------------------------------------------------------
    | ~            | 位求反
    +-----------+---------------------------------------------------------
    | **        | 幂运算
    +-----------+---------------------------------------------------------
    | <<        | 左位移
    +-----------+---------------------------------------------------------
    | >>        | 右位移
    +-----------+---------------------------------------------------------
    | &            | 位布尔和
    +-----------+---------------------------------------------------------
    | |            | 位布尔或
    +-----------+---------------------------------------------------------
    | &&        | 逻辑和
    +-----------+---------------------------------------------------------
    | ||        | 逻辑或
    +-----------+---------------------------------------------------------

可以在 if 语句中用双括号命令,也可以在脚本中的普通命令里使用来赋值。

示例:
    [devalone@devalone 12]$ cat test23.sh
    #!/bin/bash
    # using double parenthesis
    #
    val1=10
    #
    if (( $val1 ** 2 > 90 ))
    then
            (( val2=$val1 ** 2 ))
            echo "The square of $val1 is $val2"
    fi

运行:

    [devalone@devalone 12]$ test23.sh
    The square of 10 is 100

2.6.2 使用双括号 [[]]
-----------------------------------------------------------------------------------------------------------------------------------------
双方括号命令提供了针对字符串比较的高级特性。双方括号命令的格式如下:

    [[ expression ]]
    
双方括号里的 expression 使用了 test 命令中采用的标准字符串比较。但它提供了 test 命令未提供的另一个特性——模式匹配(pattern matching)。


    NOTE:
    -------------------------------------------------------------------------------------------------------------------------------------
    双方括号在 bash shell中工作良好。不过要小心,不是所有的 shell 都支持双方括号。
    

示例:

    [devalone@devalone 12]$ cat test24.sh
    #!/bin/bash
    # using pattern matching
    #
    if [[ $USER == d* ]]
    then
            echo "Hello $USER"
    else
            echo "Sorry, I do not know you"
    fi

运行:

    [devalone@devalone 12]$ test24.sh
    Hello devalone

在上面的脚本中,使用了双等号(==)。双等号将右边的字符串(d*)视为一个模式,并应用模式匹配规则。双方括号命令让 $USER 环境变量与模式进行
匹配,看它是否以字母 d 开头。如果是的话,比较通过,shell 会执行 then 部分的命令。


2.7 case 命令
-----------------------------------------------------------------------------------------------------------------------------------------
经常发现自己在尝试计算一个变量的值,在一组可能的值中寻找特定值。在这种情形下,不得不写出很长的 if-then-else 语句,就像下面这样:

    [devalone@devalone 12]$ cat test25.sh
    #!/bin/bash
    # looking for a possible value
    #
    if [ $USER = "devalone" ]
    then
        echo "Welcome $USER"
        echo "Please enjoy your visit"
    elif [ $USER = "barbara" ]
    then
        echo "Welcome $USER"
        echo "Please enjoy you visit"
    elif    [ $USER = "testing" ]
    then
        echo "Special testing account"
    elif    [ $USER = "jessica" ]
    then
            echo "Do not forget to logout when you're done"
    else
            echo "Sorry, you are not allowed here"
    fi

运行:
    [devalone@devalone 12]$ test25.sh
    Welcome devalone
    Please enjoy your visit

elif 语句继续 if-then 检查,为比较变量寻找特定的值。

有了 case 命令,就不需要再写出所有的 elif 语句来不停地检查同一个变量的值了。case 命令会采用列表格式来检查单个变量的多个值。

case 格式如下:

    case variable in
        pattern1 | pattern2) commands1;;
        pattern3) commands2;;
        *) default commands;;
    esac

case 命令会将指定的变量与不同模式进行比较。如果变量和模式是匹配的,那么 shell 会执行为该模式指定的命令。可以通过竖线操作符在一行中分隔出
多个模式。星号会捕获所有与已知模式不匹配的值。

示例:

    [devalone@devalone 12]$ cat test26.sh
    #!/bin/bash
    # using the case command
    #
    case $USER in
            devalone | barbara)
                    echo "Welcome, $USER"
                    echo "Please enjoy your visit";;
            testing)
                    echo "Special testing account";;
            jessica)
                    echo "Do not forget to log off when you're done";;
            *)
                    echo "Sorry, you are not allowed here";;
    esac

运行:

    [devalone@devalone 12]$ test26.sh
    Welcome, devalone
    Please enjoy your visit

case 命令提供了一个更清晰的方法来为变量每个可能的值指定不同的选项。

 

系列目录:

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

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

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

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

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

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

 

-----------------------------------------------------------------------------------------------------------------------------------------

参考:

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

20231126-超详细Isaac Gym安装教程(基于双系统版本) 我一开始使用了WSL2虚拟环境试了集群服务器里面的交互式桌面,但是都失败了,WSL2因为没办法调用系统的GPU,应该有办法配置但我放弃了,感兴趣的可以自己探索(图片贴出来了)。服务器上出现的问题是Segmentation fault (core dumped),目前还没解决,有可能是驱动和cuda版本的问题(后面有时间再解决)等上图右边都达到了100%,就创建了一个名为rlgpu的conda环境,然后会出现success。注意安装版本要低于3.9!参考链接:非常详细,大家直接看这个博主的安装就行。 阅读详情

相关推荐

计算机组成原理实验二 运算器组成实验

事实上,ALU的设计是在全加器的基础上,对全加器功能的扩展来实现符合要求的多种算术/逻辑运算的功能。为了实现多种功能的运算,An、Bn数据是不能直接与全加器相连接的,它们受到功能变量F3—F1的制约,因此,可由An、Bn数据和功能变量F3-F1组合成新的函数Xn 、Yn,然后,再将Xn 、Yn和下一位进位Cn-1通过全加器进行全加运算以实现所需的运算功能。AC寄存器可用来存储ALU的输入以实现两个操作数的运算操作,也可以用来存储来自ALU的结果,以将这些结果反馈给ALU以进行更多的处理。

qq_63574533的博客 1451

PG数据库安装

【转】postgresql 9.4 在linux环境的安装步骤详解 本文章来为各位介绍一篇关于postgresql 9.4 在linux环境的安装步骤详解,希望文章能够对各位新手朋友带来帮助的哦。 环境说明 系统:centos 6.4 64位 软件:postgresql 9.4.1     软件下载 cd /usr/local/src/ wget https://ftp.postgresql....

qq_35900437的博客 6626

BES平台集成第三方音频算法避坑指南:以声加ENC为例,聊聊文件放置、内存分配与授权那些事

本文详细解析了在BES平台上集成声加ENC降噪算法的全流程,包括技术选型、系统架构设计、内存管理及量产授权等关键环节。特别针对BES平台的双核架构和内存限制,提供了文件放置、内存分配与授权验证的实用解决方案,帮助开发者高效实现音频算法集成。

weixin_33720956的博客 515

[MQTT]Mosquitto的權限管理_使用者/密碼(pwfile)和訪問控制清單(aclfile)

在mosquitto的權限管理部分,除了設置使用者/密碼(pwfile)之外,還有訪問控制清單(Access Control List, aclfile)可以設置。經過測試,同時設置使用者/密碼和訪問控制清單,對於權限有實質的控管效果。

分享实用工具、好书阅读、教育学习与思维概念等等多元化的主题。 1087

VS Code配置MASM32汇编环境:从安装到调试的完整指南

本文提供了一份详尽的指南,教你如何在VS Code中配置MASM32汇编开发环境,实现从安装、环境变量设置到编写、编译和调试32位Windows汇编窗口程序的完整工作流。通过集成现代编辑器的便利性与经典汇编工具链,旨在降低学习门槛,提升底层开发效率。

nn3456的博客 487

长鑫存储面试真题解析:DRAM工程师的工程直觉与产线思维

DRAM作为现代计算系统的底层存储基石,其性能与可靠性高度依赖半导体物理基础、工艺窗口控制和电路-系统协同设计。理解电荷保持机制、位线电容耦合效应、信号完整性约束等核心原理,是突破传统数字IC思维、构建真实产线语感的关键。在晶圆厂级工程实践中,TEM缺陷识别、BIST空间聚类分析、Retention失效定位等能力,直接关联良率爬坡与客户系统稳定性。本文聚焦长鑫存储一线技术面试中高频出现的工艺-电路-测试三维问题,融合‘电荷保持’‘信号完整性’等热词,还原DRAM工程师必备的系统性建模能力与闭环验证思维,覆盖

weixin_34293246的博客 337

Shell中的if、then、elif、else——流程控制语句

流程控制——if 1. 单分支if条件语句 语法: if [ 条件判断式 ];then 程序 fi 或者 if [ 条件判断式 ] then 程序 fi 注意事项: if语句使用fi结尾,和一般语言使用大括号结尾不同 [ 条件判断式 ]就是使用test命令判断,所以中括号和条件判断式之间必须有空格。 then后面跟符合条件之后执行的程序,可以放在[]之后,用“;”分割。也可以换行写入,就不需要“;”了。 示例1:统计根分区使用率 制作一个脚本,用来统计根分区的使用率。 我们先给出全部的代码,

IChen.的博客 1万+

多智能体强化学习论文——SEAC(NIPS 2020)

存在的问题&研究动机&研究思路 在稀疏奖励的环境下,多智能体的exploration存在效率不足等问题。 在IAC的基础上尝试加入重要性采样,使得每次更新智能体iii的参数时,不再仅仅使用智能体iii的数据,而是使用所有智能体的数据进行智能体iii数据的更新。 对于原始的IAC算法是on-policy的,而SEAC则是off-poligy的。 创新点 在每个智能体iii的actoriactor_iactori​和criticicritic_icritici​的更新过程中,都加入了重要性

我的AI笔记 1207

不看后悔系列之一篇搞懂LinuxCentOS搭建MQTT服务器及客户端操作使用

看完绝对让你直呼通透!花了将近一天的时间,吐血总结~

永远热泪盈眶 坚持输出 6436

DataGrip 2023.3 Windows版激活保姆级教程:从下载脚本到输入激活码,一次搞定

本文提供DataGrip 2023.3 Windows版的完整安装与授权指南,从环境准备到数据库连接管理,再到高效开发技巧与高级功能扩展,帮助开发者快速掌握这一专业数据库管理工具。内容涵盖安装步骤、初始配置、常见问题解决及性能调优技巧,适合数据库开发新手和专业人士。

weixin_30275415的博客 645

大数据ZooKeeper(一):ZooKeeper基本知识

Zookeeper是一个分布式协调服务的开源框架。主要用来解决分布式集群中应用系统的一致性问题。ZooKeeper本质上是一个。

Lansonli(蓝深李)的博客 3150

oracle12跟11的区别,详解12c的v$pwfileuser视图和Oracle11g区别_Oracle视频_Oracle学习视频_Oracle系统_课课家...

我们一起看看详解12c的v$pwfile_user视图和Oracle11g区别。V$PWFILE_USERS 列出的是password文件里已授予sysdba、sysoper权限的用户,如果查询没有记录,那就有可能没有了password文件了,没有了密码文件当然sqlplus sys/xx as sysdba这种用sys用sysdba用户就无法登录了。下面介绍一下11g和12c的v$pwfile_...

weixin_42106357的博客 350

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

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

继 Linux shell 脚本编程-高级篇 (一) 2. 图形化桌面环境中的脚本编程   2.1 创建文本菜单 创建交互式 shell 脚本最常用的方法是使用菜单。提供各种选项可以帮助脚本用户了解脚本能做什么和不能做什么。   通常菜单脚本会清空显示区域,然后显示可用的选项列表。用户可以按下与每个选项关联的字母或数字来选择选项。 shell 脚本菜单的核心是 case 命令。ca...

devalone 的专栏 1898

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

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

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

weixin_55767624的博客 2723

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

【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

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

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

SHELL 脚本编程基础

文章目录1. shell 概述1.1 shell 和 shell 脚本1.2 Shell 脚本应用场景1.4 shell 类型 1. shell 概述 1.1 shell 和 shell 脚本   shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务,在用户和内核之间充当翻译官的角色,是一个命令解释器。Ken Thompson 的 sh 是第一种 Unix Shell,Windows Explorer 是一个典型的图形界面 shell。   shell 脚本(

shenyuanhaojie的博客 3万+

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

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

weixin_55767624的博客 1738

shell 编程基础

shell编程基础

qq_67582098的博客 1883

Linux基础之初识SHELL脚本

Shell脚本(Shell Script )可以简单理解为多个LINUX命令的堆砌,与Windows/Dos下的批处理相似

高飞的博客 31万+

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

Shell脚本编程基础篇(1)

shell在英文中翻译为"贝壳",在贝壳内部就是linux系统内核,在贝壳外部就是用户。Shell 是一个应用程序,它连接了用户和 Linux 内核,让用户能够更加高效、安全、低成本地使用 Linux 内核,这就是 Shell 的本质。Shell 本身并不是内核的一部分,它只是站在内核的基础上编写的一个应用程序。对于shell而言,就是用户与内核之间的媒介。

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

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值