Lecture 2 Shell Tools and Scripting

发布时间 2024-01-03 20:05:31作者: viewoverlook

Lecture 2 Shell Tools and Scripting

homework:

1.Read man ls and write an ls command that lists files in the following manner
读取 man ls 并编写按以下方式列出文件的 ls 命令

Includes all files, including hidden files
包括所有文件,包括隐藏文件
Sizes are listed in human readable format (e.g. 454M instead of 454279954)
尺寸以人类可读的格式列出(例如 454M 而不是 454279954)
Files are ordered by recency 文件按新近度排序
Output is colorized 输出已着色
A sample output would look like this
示例输出如下所示

 -rw-r--r--   1 user group 1.1M Jan 14 09:53 baz
 drwxr-xr-x   5 user group  160 Jan 14 09:53 .
 -rw-r--r--   1 user group  514 Jan 14 06:42 bar
 -rw-r--r--   1 user group 106M Jan 13 12:12 foo
 drwx------+ 47 user group 1.5K Jan 12 18:08 ..
  1. 先man ls找具体命令要用 -l -h -t -c
  2. 执行
ls -l -h -t -c

效果:

  1. Write bash functions marco and polo that do the following. Whenever you execute marco the current working directory should be saved in some manner, then when you execute polo, no matter what directory you are in, polo should cd you back to the directory where you executed marco. For ease of debugging you can write the code in a file marco.sh and (re)load the definitions to your shell by executing source marco.sh.
    编写执行以下操作的 bash 函数 marco 和 polo 。每当你执行 marco 时,当前工作目录应该以某种方式保存,那么当你执行 polo 时,无论你在哪个目录, polo 都应该 cd 你回到你执行 marco 的目录。为了便于调试,您可以将代码编写在文件 marco.sh 中,并通过执行 source marco.sh 将定义(重新)加载到 shell 中。
marco(){
       export MARCO=$(pwd)
}
polo(){
       cd "$MARCO"
}

解释:

  • export命令将新增MARCO内的内容到其之后所有创建的子进程中,在相同脚本中相当于定义全局变量,不同的脚本中直接引入即可。
  • source 将脚本内嵌到shell中,这时脚本中的命令可以直接执行
  • 注意"$"的好多用法
  1. Say you have a command that fails rarely. In order to debug it you need to capture its output but it can be time consuming to get a failure run. Write a bash script that runs the following script until it fails and captures its standard output and error streams to files and prints everything at the end. Bonus points if you can also report how many runs it took for the script to fail.
    假设您有一个很少失败的命令。为了调试它,您需要捕获其输出,但运行失败可能很耗时。编写一个 bash 脚本,该脚本运行以下脚本,直到它失败并将其标准输出和错误流捕获到文件并在最后打印所有内容。如果还可以报告脚本失败所花费的运行次数,则为奖励积分。
 #!/usr/bin/env bash

 n=$(( RANDOM % 100 ))

 if [[ n -eq 42 ]]; then
    echo "Something went wrong"
    >&2 echo "The error was using magic numbers"
    exit 1
 fi

上网查一查shell中for或者while循环的语法即可,若将n改为对我文件进行执行,然后-eq参数改为0,不断循环然后加一个变量记录循环次数即可

  1. echo "Everything went according to plan"
    As we covered in the lecture find’s -exec can be very powerful for performing operations over the files we are searching for. However, what if we want to do something with all the files, like creating a zip file? As you have seen so far commands will take input from both arguments and STDIN. When piping commands, we are connecting STDOUT to STDIN, but some commands like tar take inputs from arguments. To bridge this disconnect there’s the xargs command which will execute a command using STDIN as arguments. For example ls | xargs rm will delete the files in the current directory.
    正如我们在讲座中介绍的那样 find 的 -exec 对于对我们正在寻找的文件执行操作非常强大。但是,如果我们想对所有文件执行某些操作,例如创建zip文件,该怎么办?如您所见,命令将从参数和 STDIN 中获取输入。管道命令时,我们将 STDOUT 连接到 STDIN,但像 tar 这样的命令从参数中获取输入。为了弥合这种断开连接,有 xargs 命令,它将使用STDIN作为参数执行命令。例如 ls | xargs rm 将删除当前目录中的文件。
    Your task is to write a command that recursively finds all HTML files in the folder and makes a zip with them. Note that your command should work even if the files have spaces (hint: check -d flag for xargs).
    您的任务是编写一个命令,该命令以递归方式查找文件夹中的所有 HTML 文件,并用它们制作一个 zip。请注意,即使文件有空格,您的命令也应该有效(提示:检查 -d 标志的 xargs )。
    If you’re on macOS, note that the default BSD find is different from the one included in GNU coreutils. You can use -print0 on find and the -0 flag on xargs. As a macOS user, you should be aware that command-line utilities shipped with macOS may differ from the GNU counterparts; you can install the GNU versions if you like by using brew.
    如果您使用的是 macOS,请注意默认的 BSD find 与 GNU coreutils 中包含的不同。您可以在 find 上使用 -print0 ,在 xargs 上使用 -0 标志。作为 macOS 用户,您应该知道 macOS 附带的命令行实用程序可能与 GNU 对应工具不同;如果您愿意,您可以使用 brew 安装 GNU 版本。
find . -type f -name "*.html" -print0 | xargs -0 tar -czf html_files.zip

解释:

  1. find命令递归的寻找指定目录下所有符合条件的文件:用'.'代表在当前目录下寻找, -type f 寻找普通的file文件 -name指定名称 -print0 将文件名以null字符分隔输出(\0)
  2. | xargs -0 从管道左侧接受以null分隔符的输入流
  3. tar -czf html_files.zip 此时xargs传递的输入符合tar的输入要求链接了tar命令和find

tar: 压缩、打包命令
-c: 创建一个新的压缩包
-z: 使用 gzip 压缩算法进行压缩
-f: 指定压缩包的文件名
html_files.zip: 压缩包的文件名,可以根据需要修改

  1. (Advanced) Write a command or script to recursively find the most recently modified file in a directory. More generally, can you list all files by recency?
    (高级)编写命令或脚本以递归方式查找目录中最近修改的文件。更一般地说,您可以按新近度列出所有文件吗?
find . -type f -printf '%T+ %p\n' | sort -r | head -n 1 | cut -d' ' -f2-

查找最近修改过的文件,解释:
-printf '%T+ %p\n' 输出以时间在前,之后加上路径
sort -r :即reverse把时间按照倒序进行处理
head -n 1 :只取第一个
cut -d' ' -f2-:从输出中删除修改时间,只保留文件路径

find . -type f -printf '%T+ %p\n' | sort -r | cut -d' ' -f2-

实现新近度排列只需要不要head的那个命令即可