Skip to content

Lecture2 Shell 工具和脚本

:material-circle-edit-outline: 约 716 个字 :fontawesome-solid-code: 36 行代码 :material-clock-time-two-outline: 预计阅读时间 3 分钟

[自制双语字幕] 计算机教育缺失的一课(2020) - 第2讲 - Shell 工具和脚本_哔哩哔哩_bilibili

空格

可能在使用高级编程语言时我们会习惯用空格增强可阅读性,但是在shell里面写指令时不要随便加空格,因为在shell里面,空格是用于分隔参数的字符,即空格意味着参数,加空格可能导致shell将变量当成程序进行调用的情况。

大多数shell都有自己的一套脚本语言,包括变量、控制流和自己的语法。

shell脚本与其他脚本语言不同之处在于,shell 脚本针对 shell 所从事的相关工作进行来优化。因此,创建命令流程(pipelines)、将结果保存到文件、从标准输入中读取输入,这些都是 shell 脚本中的原生操作,这让它比通用的脚本语言更易用。

本节中,我们会专注于 bash 脚本,因为它最流行,应用更为广泛。

变量

定义变量:foo=bar

调用变量:echo "value is $foo"

如果用单引号的话会打印不会替换变量,会直接打印$foo

一般都用双引号

特殊变量

关键字 解释 备注
$_ 上一条命令的最后一个参数
!! 上一条命令直接复制过来 发现没有权限后直接sudo !!
$n 接收shell脚本文件执行时传入的参数 n为数字,n=0获取脚本文件名,其它为第n个参数,多位数需要给数字加{},如:$1,${12}
$@ 获取所有传入参数 拼接在其一起,但实际为数组
$* 获取所有传入参数 拼接在其一起
$# shell脚本所有输入参数的个数
$? 获取上一个shell命令的退出状态码,或者是函数的返回值 得到0就代表执行成功,非0就是不成功
常用echo $? 检查上一条指令是否成功执行
$$ 获取当前shell环境的进程ID号(pid)

一些操作

命令可用;分开执行,如:

false ||echo "hello"; echo "fcho"

变量赋值:

foo=$(pwd)
echo $foo

命令替换:

echo "hellow $(pwd)"

进程替换:

cat < ls < (ls ..)

用vim查看文件:

vim file

ls列出特定的文件:

ls *.sh     #列出所有.sh文件
ls project? #列出名为project?的文件,?是通配符,表示任意一个字符

简写:

convert image.png image.jpg
convert image.{png,jpg} #与上面等效

touch foo{,1,2,10}
touch foo foo1 foo2 foo10

#可以这样进行笛卡尔积
touch project{1,2,3}/src/test{1,2,3}.py
touch {foo,bar}/{a..j}  #a..j是a~j的缩写

示例

函数示例

mcd () {
    mkdir -p "$1"
    cd "$1"
}

脚本示例

#!/bin/bash

echo "Starting program at $(date)" # date会被替换成日期和时间

echo "Running program $0 with $# arguments with pid $$"

for file in "$@"; do
    grep foobar "$file" > /dev/null 2> /dev/null
    # 如果模式没有找到,则grep退出状态为 1
    # 我们将标准输出流和标准错误流重定向到Null,因为我们并不关心这些信息
    if [[ $? -ne 0 ]]; then
        echo "File $file does not have any foobar, adding one"
        echo "# foobar" >> "$file"
    fi
done

-ne 表示不等于

python

python脚本可以通过python xx.py的指令让shell执行。

想让shell直接能够运行python脚本,可以将 .py 文件的 shebang(#!) 行改成/usr/bin/env python

其它

指令 作用 备注
tldr man的替代品 必须sudo
find 查找某些文件路径 find [dir] -name [text] -type [d/f] -path '**/test/*.py' -mtime -1 -exec [instruction](加指令)
fd find . -name
locate
grep grep -R会遍历整个目录
rg
history history 1表示列出所有操作
history 1 | grep convert
fzf 模糊搜索
tree

ctrl + R:反向搜索