https://missing.csail.mit.edu/https://missing-semester-cn.g...https://www.bilibili.com/vide...注释Shell脚本特殊变量$0-脚本名称$1到$9-脚本的参数。$1是第一个参数,依此类推。$@-所有参数$#-参数数量$?-前一个命令的返回值$$-当前脚本的进程ID!!-完成最后一条命令,包括参数。常见应用:当你因为权限不足导致执行命令失败时,可以使用sudo!!再试一次。$_-上一个命令的最后一个参数。如果您使用的是交互式shell,则可以通过按Esc然后键入来获取此值。进程替换一个不太流行的类似特性是进程替换(processsubstitution),<(CMD)会执行CMD并将结果输出到一个临时文件,将<(CMD)替换为临时文件名。当我们希望通过文件而不是STDIN传递返回值时,这很有用。例如,diff<(lsfoo)<(lsbar)将显示文件夹foo和bar中的文件之间的差异。globbingconvertimage.{png,jpg}#将扩展为convertimage.pngimage.jpgcp/path/to/project/{foo,bar,baz}.sh/newpath#将扩展为cp/path/to/project/foo.sh/path/to/project/bar.sh/path/to/project/baz.sh/newpath#也可以与通配符组合mv*{.py,.sh}folder#将移动所有*.py和*.sh文件mkdirfoobar#下面的命令会创建foo/a,foo/b,...foo/h,bar/a,bar/b,...bar/h这些文件touch{foo,bar}/{a..h}touchfoo/xbar/y#showdiffoffooandbarfiles<(lsfoo)<(lsbar)#output#yshebang注意,脚本不一定必须用bash编写才能在终端中调用。例如,这是一个以相反顺序输出输入参数的Python脚本:#!/usr/local/bin/pythonimportsysforarginreversed(sys.argv[1:]):print(arg)shell知道go此脚本使用python解释器而不是shell命令运行,因为脚本开头第一行的shebang)。最好在shebang行使用env命令,它将使用环境变量中的程序来解析脚本,从而提高脚本的可移植性。env将利用我们第一堂课中介绍的PATH环境变量来定位。例如,使用env的shebang看起来像#!/usr/bin/envpython。shellcheck编写bash脚本有时可能很笨拙且违反直觉。shellcheck等工具可以帮助您定位sh/bash脚本中的错误。例如:查看命令如何使用tldrcheat查找文件的Shell工具findlocatefdlocate与find。搜索代码示例greprgackaggrep:rg示例:#查找所有使用请求库的文件rg-tpy'importrequests'#查找所有没有shebang的文件(包括隐藏文件)rg-u--files-without-match"^#!"#查找所有foo字符串,并打印接下来的5行rgfoo-A5#打印匹配统计信息(匹配行数和文件数)rg--statsPATTERNfindshellcommandhistory|历史|fzf快捷键Ctrl+R自动补全:fishshell或zsh-autosuggestions值得注意的是,在键入命令时,如果在命令开头添加空格,则不会添加到shell记录中。当您输入包含密码或其他敏感信息的命令时,将使用此功能。如果不小心忘记前面加空格,可以编辑。bash_history或.zhistory手动从历史记录中删除该项目。文件夹导航fasdautojump:ohmyzshtreerangerOh-my-zsh?对于初学者,请阅读这篇文章:设置Windows终端、WSL和Oh-my-Zsh课后练习练习1练习2macro.sh:macro(){macro_dir=$(pwd)echo"Iamin$macro_dir"|tee/mnt/f/code/learn/missing-semester/l2-shell-tools/macro.txt}polo.sh:polo(){cd"$macro_dir"||复制代码退出宏}练习3ex3_solution.sh:#!/usr/bin/envbash./ex3_problem.sh>ex3_result.txt2>ex3_result.txtstate=$?count=0while[[state-eq0]];做./ex3_problem.sh>>ex3_result.txt2>>ex3_result.txtstate=$?count=$((count+1))donecatex3_result.txttechcho"ex3_problemrun$counttimesbeforefailure"Exercise4$treeex4_html_folderex4_html_folder├──1.html├──1.txt├──a│├──a1.html│├──a1.txt│├──a2.txt│└──a3.txt└──b├──b1.html├──b2.html└──b3.html2目录,9个文件参考tldrxargs给出的用法示例:-删除所有扩展名为.backup的文件(-print0使用空字符分割文件名,-0作为分隔符呃):找到。-名称{{'*.backup'}}-print0|xargs-0rm-vtldrtar给出了tar命令的用法示例:-[c]从[f]iles中创建一个存档:tarcf{{target.tar}}{{file1}}{{file2}}{{file3}}-E[x]tracta(compressed)archive[f]ile到目标目录:tarxf{{source.tar[.gz|.bz2|.xz]}}--directory={{directory}}-Lis[t]一个tar[f]ile的内容[v]erbosely:tartvf{{source.tar}}所以这个问题答案如下:find.-name"*.html"-print0|xargs-0tarcfhtml.tar验证它:$tartvfhtml.tar-rwxrwxrwxyzj/yzj02021-01-2915:00./ex4_html_folder/1.html-rwxrwxrwxyzj/yzj02021-01-2915:25./ex4_html_folder/a/a1.html-rwxrwxrwxyzj/yzj02021-01-2915:25./ex4_html_folder/b/b1.html-rwxrwxrwxyzj/yzj02021-01-2915:25./ex4_html_folder/b/b2.html-rwxrwxrwxyzj/yzj02021-01-2915:25./ex4_html_folder/b/b3.html$mkdirex4_html_folder_extracted$tarxfhtml.tar--directory=ex4_html_folder_extracted$树ex4_html_folder_extractedex4_html_folder_extracted└──ex4_html_folder├──1.html├──a│└──a1.html└──b├──b1.html├──b2.html└──b3.html3目录,上面5个文件的解决方法是将find命令输出的分隔符??由原来的换行符改为null,然后让xargs也使用null作为分隔符你也可以使用-d选项来指定一个换行符作为分隔符,所以另一种解决方案如下:find。-名称“*.html”|xargs-d"\n"tarcfhtml.tar练习5#按最近修改的顺序列出文件$find.-类型f-print0|xargs-0ls-lt--color-rwxrwxrwx1yzjyzj10240Jan2915:27./html.tar-rwxrwxrwx1yzjyzj0Jan2915:25'./ex4_html_folder/a/a1.html'-rwxrwxrwx1yzjyzj01月29日15:25'./ex4_html_folder_extracted/ex4_html_folder/a/a1.html'-rwxrwxrwx1yzjyzj01月29日15:25'./ex4_html_folder/a/a3.txt'-rwxrwxrwx1yzjyzj0Jan2915:25'./ex4_html_folder/a/a2.txt'-rwxrwxrwx1yzjyzj0Jan2915:25'./ex4_html_folder/a/a1.txt'-rwxrwxrwx1yzjyzj0Jan2915:25'./ex4_html_folder/b/b1.html'-rwxrwxrwx1yzjyzj0Jan2915:25'./ex4_html_folder/b/b2.html'-rwxrwxrwx1yzjyzj0Jan2915:25'./ex4_html_folder/b/b3.html'-rwxrwxrwx1yzjyzj0Jan2915:25'./ex4_html_folder_extracted/ex4_html_folder/b/b1.html'-rwxrwxrwx1jzj0Jan2915:25'./ex4_html_folder_extracted/ex4_html_folder/b/b2.html'-rwxrwxrwx1izjizj0Jan2915:25'./ex4_html_folder_extracted/ex4_html_folder/b/b3.html'-rwxrwxrwx1izjizj0Jan2915:01./ex4_html_folder/1.txt-rwxrwxrwx1提取0Jan2915:00./ex4_html_folder/1.html-rwxrwxrwx1提取0Jan2915:00./ex4_html_folder_extracted/ex4_html_folder/1.html-rwxrwxrwx1提取837Jan2910:0014./ex3_result.txt-rwxrwxrwx1izjyzj291Jan2910:11./ex3_solution.sh-rwxrwxrwx1izjyzj205Jan2909:58./ex3_problem.sh-rwxrwxrwx1izjyzj58Jan29.09:5/macro.txt-rwxrwxrwx1izjizj49Jan2909:48./polo.sh-rwxrwxrwx1izjizj129Jan2909:44./macro.sh-rwxrwxrwx1izjizj50Jan2821:41./mcd.sh-rwxrwxrwx1izjizj509Jan2821:10./example.sh#查找最近修改的文件$find.-类型f-print0|xargs-0ls-lt--颜色|head-n1-rwxrwxrwx1izjizj102401月29日15:27./html.tar