Lecture2 Shell 工具和脚本
:material-circle-edit-outline: 约 716 个字 :fontawesome-solid-code: 36 行代码 :material-clock-time-two-outline: 预计阅读时间 3 分钟
空格
可能在使用高级编程语言时我们会习惯用空格增强可阅读性,但是在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) | |
一些操作
命令可用;
分开执行,如:
变量赋值:
命令替换:
进程替换:
用vim查看文件:
ls列出特定的文件:
简写:
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的缩写
示例
函数示例
脚本示例
#!/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:反向搜索