的地方,最好不要假设文件放在固定的位置,其他的东西要是如此。
shebang
行中使用 env
命令,会根据给出的参数(这里是python),env
会利用之前的PATH
环境变量来进行定位,在此路径中找python二进制文件,然后用该文件去解释这个脚本。这会有更好的可移植性
#!/usr/bin/env python
import sys
for arg in reversed(sys.argv[1:]):
print(arg)
编写bash脚本有时候会很别扭和反直觉。例如 shellcheck 这样的工具可以帮助你定位sh/bash脚本中的错误。
koalaman/shellcheck at v0.7.1 (github.com)
shellcheck可以给出warning和语法错误提示,还能指出哪些地方你没正确引用等。
[lighthouse@VM-8-17-centos tools]$ shellcheck mcd.sh
In mcd.sh line 1:
mcd(){
^-- SC2148: Tips depend on target shell and yours is unknown. Add a shebang.
shell函数和脚本有如下一些不同点:
- 函数只能与shell使用相同的语言,脚本可以使用任意语言。因此在脚本中包含
shebang
是很重要的。
- 函数仅在定义时被加载,脚本会在每次被执行时加载。这让函数的加载比脚本略快一些,但每次修改函数定义,都要重新加载一次。
- 函数会在当前的shell环境中执行,脚本会在单独的进程中执行。因此,函数可以对环境变量进行更改,比如改变当前工作目录,脚本则不行。脚本需要使用
export
将环境变量导出,并将值传递给环境变量。
- 与其他程序语言一样,函数可以提高代码模块性、代码复用性并创建清晰性的结构。shell脚本中往往也会包含它们自己的函数定义。
Shell工具
查看命令如何使用
给出一个命令,应该怎样了解如何使用这个命令行并找出它的不同的选项呢?最常用的方法是为对应的命令行添加-h
或 --help
标记。另外一个更详细的方法则是使用man
命令。man
命令是手册(manual)的缩写,它提供了命令的用户手册。
事实上,目前我们给出的所有命令的说明链接,都是网页版的Linux命令手册,即使是安装的第三方命令。当然前提是开发者编写了手册并将其包含在了安装包中。在交互式的、基于字符处理的终端窗口中,一般也可以通过 :help
命令或键入 ?
来获取帮助。
- tldr (too long don't read)
有时候手册内容太过详实,让我们难以在其中查找哪些最常用的标记和语法。TLDR pages是一个很不错的替代品,它提供了一些案例,可以帮助你快速找到正确的选项。
下载tldr:npm install -g tldr
使用npm命令之前要先下载 yum -y install npm
查找文件
你当然可以使用ls,但是如果你想查找一个已经知道名字的文件或者目录,我们可以有更好的做法
linux-find
find大概是每个UNIX系统都有的工具,例如
[lighthouse@VM-8-17-centos tools]$ find . -name src -type d
./project1/src
./project2/src
这里意为,在当前文件夹.
调用find,查找名为src
并且类型为目录的东西。键入以上命令,它就可以在当前目录递归查看所有符合规则的文件或者文件夹(find默认递归指定目录)。
find还有许多有用的flag,比如你甚至可以查询指定格式的文件路径:
[lighthouse@VM-8-17-centos tools]$ find . -path '**/test/*.py' -type f
./project1/src/test/test2.py
./project1/src/test/test1.py
./project1/src/test/test3.py
./project2/src/test/test2.py
./project2/src/test/test1.py
./project2/src/test/test3.py
这里**
是指可以匹配零或者多个目录名,然后在此路径下找到拓展名为.py
的文件,并要求它们在一个test文件夹内,同时检查它是否为F类型(f代表文件file)
运用不用的flag,可以进行非路径和非文件名的筛选:
比如可以查找被修改过的文件,这里-mtime
代表修改时间,.
当前目录下,最近1
天被修改过的东西都会被列出
[lighthouse@VM-8-17-centos tools]$ find . -mtime -1
.
./project1
./project1/src
./project1/src/test
./project1/src/test/test2.py
./project1/src/test/test1.py
./project1/src/test/test3.py
./project2
./project2/src
./project2/src/test
./project2/src/test/test2.py
./project2/src/test/test1.py
./project2/src/test/test3.py
./test
./mcd.sh
你甚至可以使用其他条件,比如大小,所有者,权限等等。
强大的是,find不仅可以查找东西,找到之后还可以做别的:例如
我们可以在当前目录下查找所有扩展名为.tmp
的文件,然后要求find对于所有这些文件,执行rm
命令
[lighthouse@VM-8-17-centos tools]$ find . -name "*.tmp"
./project1/src/test/test3.tmp
./project1/src/test/test1.tmp
./project1/src/test/test2.tmp
./project2/src/test/test3.tmp
./project2/src/test/test1.tmp
./project2/src/test/test2.tmp
[lighthouse@VM-8-17-centos tools]$ find . -name "*.tmp" -exec rm {} \;
[lighthouse@VM-8-17-centos tools]$ echo $?
0
[lighthouse@VM-8-17-centos tools]$ find . -name "*.tmp"
[lighthouse@VM-8-17-centos tools]$
如上,执行find . -name "*.tmp" -exec rm {} \;
后,对应的tmp文件都被删除了。
fd
是一个更简单、更快速、更友好的程序,它可以用来作为find
的替代品。它有很多不错的默认设置,例如输出着色、默认支持正则匹配、支持unicode并且我认为它的语法更符合直觉。以模式PATTERN
搜索的语法是 fd PATTER