美文网首页js css html
Shell 脚本学习

Shell 脚本学习

作者: 越前君 | 来源:发表于2022-06-27 23:07 被阅读0次
    配图源自 Freepik

    前言

    虽然一直都在用,但有些命令仍是半知半懂的,所以就好好学一下吧。

    一些辅助工具:

    • shellcheck - Shell 脚本静态检查工具,主流编辑器都有插件。类似 ESLint 的工具。
    • zx - Google 出品,用 JavaScript 写 Shell 脚本。

    本文大部分内容来自阮一峰老师的 Bash 脚本教程

    一、Shell 命令格式

    $ command [ arg1 ... [ argN ] ]
    

    其中 command 是一个具体的命令或者一个可执行文件,arg1... argN 是传递给命令的参数,是可选的。

    命令与参数,参数与参数之间通过「一个空格」隔开。若有「多个空格」,多余空格会被自动忽略,作用相当于一个空格。

    $ ls -l
    

    其中 ls 是命令,-l 是参数。有些参数是命令的配置项,它们一般以一个「短横线」开头,比如上面的 -l。通常配置项参数有短形式和长形式两种形式,比如 -l 是短形式,--list 是长形式。两种写法作用完全相同,短形式便于输入,长形式可读性、语义更好。

    通常命令都是一行的,可有些命令较长,写成多行有利于阅读和编辑,只要在每行结尾处加上反斜杠 \ 可以,Shell 会将下一行跟当前行一起解析。

    $ echo Hello World
    
    # 等同于
    $ echo Hello \
    World
    

    二、命令的组合与继发

    命令组合符 &&,前一个命令执行成功,才会接着执行第二个命令。

    $ command1 && command2
    

    命令组合符 ||,前一个命令执行失败,才会接着执行第二个命令。

    $ command1 || command2
    

    命令结束符 ;(分号),前一个命令执行结束后(无论成功与否),接着执行第二个命令。命令结束符可使得一行中放置多个命令。

    $ clear; ls
    

    管道符 |,前一个命令的输出作为第二个命令的输入。

    $ command1 | command2
    

    三、引号

    • 单引号:单引号用于保留字符的字面含义,各种特殊字符在单引号里面,都会变为普通字符。
    • 双引号:比单引号宽松,大部分特殊字符在双引号里面,都会失去特殊含义,变成普通字符。但是,三个特殊字符除外:美元符号($)、反引号(`)和反斜杠(\)。这三个字符在双引号之中,依然有特殊含义,会被 Bash 自动扩展。
    $ echo '$USER'
    $USER
    
    $ echo "$USER"
    frankie
    

    换行符在双引号之中,会失去特殊含义,Bash 不再将其解释为命令的结束,只是作为普通的换行符。所以可以利用双引号,在命令行输入多行文本。

    $ echo "hello
    world"
    
    hello
    world
    

    echo 发音 [ˈekō](才发现原来一直读错了,惭愧)。其参数 -e 会解析引号中的特殊字符(比如换行符 \n)。若在 CLI 中直接输入 echo 命令 \n 也会解析为换行符,而不是普通的 \n 字符串。

    $ echo -e "Hello\nShell"
    Hello
    Shell
    

    四、子命令扩展

    $(...) 可以扩展成另一个命令的运行结果,该命令的所有输出都会作为返回值。还有另一种较老的语法,子命令放在反引号之中,也可以扩展成命令的运行结果。

    $ echo $(date) 
    2022年 6月27日 星期一 00时31分14秒 CST
    
    $ echo `date`
    2022年 6月27日 星期一 00时32分01秒 CST
    

    五、读取变量

    • 在变量名前加上 $,比如 $SHELL
    • 读取变量时,变量名可以使用花括号 {} 包围,比如 $SHELL 可以写成 ${SHELL}
    • 如果变量的值本身也是变量,可以使用 ${!varname} 语法,读取最终的值。(好像不太对,待进一步验证)

    六、算术运算

    • 除法运算符的返回结果总是为「整数」,比如 $(( 5 / 2 )) 的结果为 2,而不是 2.5
    • $(( ... )) 的圆括号之中,不需要在变量名之前加上 $,不过加上也不报错。
    • 如果 $((...)) 里面使用不存在的变量,也会当作 0 处理。
    • $[...] 是以前的语法,也可以做整数运算,不建议使用。

    小数运算,需借助 bc 命令,其中 scale 表示小数位,ibaseobase 进行其他进制数运算。比如:

    $ var1=3
    $ var2=6  
    $ result=$(echo "scale=2; $var1 / $var2" | bc) 
    $ echo $result 
    .50
    

    七、目录堆栈

    cd - 命令可以返回前一次的目录。默认情况下,只记录上一次所在的目录。

    $ cd ~/Desktop/
    $ cd -
    ~
    

    八、脚本

    8.1 Shebang 行

    脚本的第一行通常是指定解释器,即这个脚本必须通过什么解释器执行。这一行以 #! 字符开头,这个字符称为 Shebang,所以这一行就叫做 Shebang 行。

    #! 后面就是脚本解释器的位置,Bash 脚本的解释器一般是 /bin/sh/bin/bash

    #!/bin/sh
    
    # 或者
    #!/bin/bash
    

    #! 与脚本解释器之间有没有空格,都是可以的。

    如果 Bash 解释器不放在目录 /bin,脚本就无法执行了。为了保险,可以写成下面这样。

    #!/usr/bin/env bash
    

    上面命令使用 env 命令(这个命令总是在 /usr/bin 目录),返回 Bash 可执行文件的位置。env 命令的详细介绍,请看后文。

    Shebang 行不是必需的,但是建议加上这行。如果缺少该行,就需要手动将脚本传给解释器。

    举例来说,脚本是 script.sh,有 Shebang 行的时候,可以直接调用执行。

    $ ./script.sh
    

    上面例子中,script.sh 是脚本文件名。脚本通常使用 .sh 后缀名,不过这不是必需的。

    如果没有 Shebang 行,就只能手动将脚本传给解释器来执行。

    $ /bin/sh ./script.sh
    
    # 或者
    $ bash ./script.sh
    

    8.2 执行权限和路径

    前面说过,只要指定了 Shebang 行的脚本,可以直接执行。这有一个前提条件,就是脚本需要有执行权限。可以使用下面的命令,赋予脚本执行权限。

    给所有用户执行权限

    $ chmod +x script.sh
    

    给所有用户读权限和执行权限

    $ chmod +rx script.sh
    
    # 或者
    $ chmod 755 script.sh
    

    只给脚本拥有者读权限和执行权限

    $ chmod u+rx script.sh
    

    脚本的权限通常设为 755(拥有者有所有权限,其他人有读和执行权限)或者 700(只有拥有者可以执行)。

    除了执行权限,脚本调用时,一般需要指定脚本的路径(比如 path/script.sh)。如果将脚本放在环境变量 $PATH 指定的目录中,就不需要指定路径了。因为 Bash 会自动到这些目录中,寻找是否存在同名的可执行文件。

    建议在主目录新建一个 ~/bin 子目录,专门存放可执行脚本,然后把 ~/bin 加入 $PATH

    export PATH=$PATH:~/bin
    

    上面命令改变环境变量 $PATH,将 ~/bin 添加到 $PATH 的末尾。可以将这一行加到 ~/.zshrc 文件里面,然后重新加载一次 .zshrc,这个配置就可以生效了。

    $ source ~/.zshrc
    

    以后不管在什么目录,直接输入脚本文件名,脚本就会执行。

    $ script.sh
    

    上面命令没有指定脚本路径,因为 script.sh$PATH 指定的目录中。

    上面的配置文件,取决于你当前所用的 Shell。比如我这里是 zsh,配置文件为 ~/.zshrc,如果你是 bash,可能是 ~/.bash_profile~/.bashrc 等。

    未完待续...

    相关文章

      网友评论

        本文标题:Shell 脚本学习

        本文链接:https://www.haomeiwen.com/subject/xixnvrtx.html