Shell Tools and Scripting
Shell Tools and Scripting
变量 函数
在shell中要注意空格的使用,尤其是在进行与名字字符串中带有空格的文件有关的操作时。"$ variable name"
可以使用变量。source function
可以在shell中执行函数,然后function folder/file
就可以检验了。$0
是脚本名称,$?
获取上一个命令的错误代码,$_
获取上一个命令参数,例如文件或文件夹等,$#
给出的参数数量,$$
获取pid(process id),$@
扩展到所有参数。
常见的退出状态码示例:
- 1: 一般表示命令执行时出现了错误。
- 2: 可能表示命令使用不正确,例如参数错误。
- 127: 表示命令未找到。
- 126: 表示命令找到,但无法执行(例如没有执行权限)。
!!
表示获取上一段命令,例如上一段命令执行结果是没有管理员权限,那么可以sudo !!
来解决。
运算符
||
或,&&
与,;
分隔多个命令,顺序执行。$(command)
也可以代表相应的输出内容,cat <(command)
也可以实现输出内容。
/dev/null
在类Unix系统中是一个特殊的设备文件,常被称为“空设备”或“比特桶”。你可以把它想象成一个无底洞,任何写入到它的数据都会被丢弃,而从它读取数据永远只会得到一个空的回应。
/dev/null 的作用
- 丢弃输出: 当你执行一个命令,但不想看到它的输出结果时,可以将输出重定向到 /dev/null。这在自动化脚本或批量处理任务中非常常见。
- 抑制错误信息: 某些命令执行时可能会产生错误信息。如果这些错误信息对你来说无关紧要,可以将错误信息重定向到 /dev/null。
- 创建空文件: 可以通过将特定内容写入 /dev/null 来创建一个空文件。
例如:find / -name "*.tmp" -delete > /dev/null 2>&1
这条命令会查找系统中所有以.tmp
结尾的文件并删除,同时将命令的标准输出和标准错误输出都重定向到 /dev/null,避免在终端显示任何信息。2>&1
这是一个在 Shell 脚本中经常用到的重定向符号,用于 将标准错误输出重定向到标准输出。**2>&1
的意思就是:** 把标准错误输出(2)重定向到标准输出(1)。也就是说,原本应该显示在终端上的错误信息,现在也会和正常的输出信息一起显示。 - 标准输出(stdout): 通常是显示在终端上的输出信息,用数字 1 表示。
- 标准错误输出(stderr): 通常是显示在终端上的错误信息,用数字 2 表示。
查看、修改文件
*.sh
是大多数sehll文件扩展名。ls filename?
可以查看相应问号位数名字的文件。convert filename.{png.jpg}
可以把图片格式从png转化成jpg,也可以加名字序号。touch {folder1,folder2}/{file1..filen}
可以遍历这两个文件夹中的所有名字中含有某个字符的文件。
touch 命令是一个常用的 Linux/Unix 命令,主要用于 修改文件的时间戳 或 创建新文件。
mv -i 命令在移动或重命名文件时会 先询问用户,以避免误操作导致数据丢失。
convert可用于转换图片,ffmep可用于处理视频。
shebang
/usr/bin/env: 这部分告诉系统使用 env
命令来查找指定的可执行程序。env
命令会搜索当前用户的环境变量 PATH
,找到第一个匹配的程序。
例如:
1 |
|
用系统环境中的 Python3 解释器来执行这个脚本。
调试 查找
shellcheck *.sh
检查警告和语法错误等。tldr command
查询命令用法,是一个为命令行工具提供简明易懂的使用说明的工具。它从冗长的 man
手册中提取出最常用的用法和示例,让用户能快速上手各种命令。find
或fd
用于查找文件名字,locate
用于查找并列出所有,grep
用于查找文件或文件夹中的具体内容,rg
是ripgrep的缩写,是比grep更快的文本搜索工具,fzf
模糊查找。
例如:rg -U --files-without-match "^#\!" -t sh
表示在当前目录及其子目录中,查找所有的 shell 脚本文件(.sh),并找出那些第一行不是以 #
和 !
开头的的文件。其中^
: 表示行首。#
: 匹配字符#。\!
: 匹配字符 !。Ctrl+R
可以查找历史中出现要查找的字符的代码,每按一次就出现一条。zsh
可以提供历史推荐代码。tree
和broot
都是很好的文件搜索和管理工具。
课后练习
1、要求我们使用 ls
命令,并通过添加不同的参数来实现以下功能:
- 显示所有文件(包括隐藏文件)
- 以人类可读的格式显示文件大小
- 按照文件访问时间排序
- 使用彩色输出
答:ls -lah –color=auto
-l 以长格式显示;-a 显示所有文件,包括隐藏文件;-h 以人类可读的格式显示文件大小。
2、编写两个 bash 函数 marco
和 polo
执行下面的操作。 每当你执行 marco
时,当前的工作目录应当以某种形式保存,当执行 polo
时,无论现在处在什么目录下,都应当 cd
回到当时执行 marco
的目录。 为了方便 debug,你可以把代码写在单独的文件 marco.sh
中,并通过 source marco.sh
命令,(重新)加载函数。
答:
1 |
|
3、假设您有一个命令,它很少出错。因此为了在出错时能够对其进行调试,需要花费大量的时间重现错误并捕获输出。 编写一段 bash 脚本,运行如下的脚本直到它出错,将它的标准输出和标准错误流记录到文件,并在最后输出所有内容。
答:修改后的代码:
1 |
|
对于标准输出和标准错误输出,有如下例子:
1 |
|
4、您的任务是编写一个命令,它可以递归地查找文件夹中所有的 HTML 文件,并将它们压缩成 zip 文件。注意,即使文件名中包含空格,您的命令也应该能够正确执行。
答:find . -type f -name "*.html" -print0 | xargs -0 zip html_files.zip **使用
-print0和
xargs -0`:**
-print0
会让find
输出的文件名之间用null 字符 (\0
) 进行分隔,而不是空格或换行符。xargs -0
会识别这些 null 字符,并将整个文件名(包括空格在内)作为一个单独的参数传递。
5、编写一个命令或脚本递归的查找文件夹中最近使用的文件。更通用的做法,你可以按照最近的使用时间列出文件吗?
答:`find /path -type f -printf “%T+ %p\n” | sort -r
其中
-printf "%T+ %p\n"
: 以 “+%Y-%m-%d %H:%M:%S” 格式输出文件的访问时间和路径。sort -r
: 按时间戳逆序排序,最近访问的文件排在前面。