The missing semeseter hw2

1.阅读 man ls ,然后使用 ls 命令进行如下操作:

  • 所有文件(包括隐藏文件)
  • 文件打印以人类可以理解的格式输出 (例如,使用 454M 而不是 454279954)
  • 文件以最近访问顺序排序
  • 以彩色文本显示输出结果'
# 列出所有文件
ls -a

# 使用人类可以理解的格式(human readable)
ls -h

# 以最近访问顺序排序
ls -t

# 以彩色文本显示(大多数现代发行版Linux默认开启)
ls --color

2.编写两个 bash 函数 marco 和 polo 执行下面的操作。 每当你执行 marco 时,当前的工作目录应当以某种形式保存,当执行 polo 时,无论现在处在什么目录下,都应当 cd 回到当时执行 marco 的目录。 为了方便 debug,你可以把代码写在单独的文件 marco.sh 中,并通过 source marco.sh 命令,(重新)加载函数。

# bash.sh

  1 #!/bin/sh
  2 
  3 marco(){
  4     pwd > dir.txt
  5 }
# polo.sh 

  1 #!/bin/bash
  2 
  3 polo(){
  4     path="/tmp/dir.txt"
  5     if [[ -e "$path" ]];then # 判断文件是否存在
  6         if [[ -e "$(cat "$path")" ]];then  # 判断路径是否合法
  7             cd "$(cat "$path")"
  8         else
  9             echo "File path does not exits"
 10         fi
 11     else
 12         echo "Excute marco first"
 13     fi
 14 }

3.假设您有一个命令,它很少出错。因此为了在出错时能够对其进行调试,需要花费大量的时间重现错误并捕获输出。 编写一段 bash 脚本,运行如下的脚本直到它出错,将它的标准输出和标准错误流记录到文件,并在最后输出所有内容。 加分项:报告脚本在失败前共运行了多少次。

# tesh.sh
 
#!/usr/bin/env bash

 n=$(( RANDOM % 100 ))

 if [[ n -eq 42 ]]; then
    echo "Something went wrong"
    # &表示2不是文件名而是文件描述符
    >&2 echo "The error was using magic numbers" 
    # echo "The error was using magic numbers"  >&2 
    exit 1
 fi

 echo "Everything went according to plan"
# record.sh
  1 #!/bin/bash
  2 
  3 count=0
  4 ./test.sh > output.log 2>&1
  5 status=$?
  6 while [ $status -ne 0 ];do
  7     (( count++ ))
  8     ./test.sh >> output.log 2>&1
  9     status=$?
 10 done
 11 
 12 echo "Error before success $count times"

$?受最后一次执行的语句的状态码影响,因此避免状态码受其他语句覆盖(正确保存./test.sh的状态码)同时兼顾可读性,可以用一个中间变量来立即保存./test.sh的退出状态。

 4.本节课我们讲解的 find 命令中的 -exec 参数非常强大,它可以对我们查找的文件进行操作。但是,如果我们要对所有文件进行操作呢?例如创建一个 zip 压缩文件?我们已经知道,命令行可以从参数或标准输入接受输入。在用管道连接命令时,我们将标准输出和标准输入连接起来,但是有些命令,例如 tar 则需要从参数接受输入。这里我们可以使用 xargs 命令,它可以使用标准输入中的内容作为参数。 例如 ls | xargs rm 会删除当前目录中的所有文件。您的任务是编写一个命令,它可以递归地查找文件夹中所有的 HTML 文件,并将它们压缩成 zip 文件。注意,即使文件名中包含空格,您的命令也应该能够正确执行

通配符小魔法!

        通配符的展开是由shell在命令执行前进行的。当前路径下存在testa/ testb/两个文件夹:

(base) hniii98@ysyx:/tmp$ ls test*
testa:

testb:

此时,通配符先展开为testa和testb,然后再执行ls命令,即:

(base) hniii98@ysyx:/tmp$ ls testa
(base) hniii98@ysyx:/tmp$ ls testb

由于testa和testb存在,所以test*的展开成功。

        设想另一个场景,此时我希望在testa和testb两个文件夹下创建文件,如果用上通配符,这时候会发生什么呢?

(base) hniii98@ysyx:/tmp$ touch test*/file\ {1..9}.html
touch: cannot touch 'test*/file 1.html': No such file or directory
touch: cannot touch 'test*/file 2.html': No such file or directory
touch: cannot touch 'test*/file 3.html': No such file or directory
touch: cannot touch 'test*/file 4.html': No such file or directory
touch: cannot touch 'test*/file 5.html': No such file or directory
touch: cannot touch 'test*/file 6.html': No such file or directory
touch: cannot touch 'test*/file 7.html': No such file or directory
touch: cannot touch 'test*/file 8.html': No such file or directory
touch: cannot touch 'test*/file 9.html': No such file or directory

这是为什么呢?原来啊,通配符展开先于创建命令touch,然而此时testa和testb下的文件都还没创建,因此*并没有展开而是作为一个字符传入了touch命令。显然,并不存在test*这个文件夹,因此shell报错:No such file or directory!

TIPS:通配符在未匹配到时,作为一个普通字符保留~

解决方案:采用{}现实指定文件,即:

(base) hniii98@ysyx:/tmp$ touch test{a,b}/file\ {1..9}.html
(base) hniii98@ysyx:/tmp$ ls test*
testa:
'file 1.html'  'file 2.html'  'file 3.html'  'file 4.html'  'file 5.html'  'file 6.html'  'file 7.html'  'file 8.html'  'file 9.html'

testb:
'file 1.html'  'file 2.html'  'file 3.html'  'file 4.html'  'file 5.html'  'file 6.html'  'file 7.html'  'file 8.html'  'file 9.html'

成功创建!当然可以用其他方法例如find、xargs、管道符、通配符实现。

完整命令如下:

(base) hniii98@ysyx:/tmp$ mkdir -p testa testb
(base) hniii98@ysyx:/tmp$ touch test{a,b}/file\ {1..9}.html
(base) hniii98@ysyx:/tmp$ ls test*
testa:
'file 1.html'  'file 2.html'  'file 3.html'  'file 4.html'  'file 5.html'  'file 6.html'  'file 7.html'  'file 8.html'  'file 9.html'

testb:
'file 1.html'  'file 2.html'  'file 3.html'  'file 4.html'  'file 5.html'  'file 6.html'  'file 7.html'  'file 8.html'  'file 9.html'
(base) hniii98@ysyx:/tmp$ find test{a,b}/*html -print0 | xargs -0 zip Allhtml.zip
  adding: testa/file 1.html (stored 0%)
  adding: testa/file 2.html (stored 0%)
  adding: testa/file 3.html (stored 0%)
  adding: testa/file 4.html (stored 0%)
  adding: testa/file 5.html (stored 0%)
  adding: testa/file 6.html (stored 0%)
  adding: testa/file 7.html (stored 0%)
  adding: testa/file 8.html (stored 0%)
  adding: testa/file 9.html (stored 0%)
  adding: testb/file 1.html (stored 0%)
  adding: testb/file 2.html (stored 0%)
  adding: testb/file 3.html (stored 0%)
  adding: testb/file 4.html (stored 0%)
  adding: testb/file 5.html (stored 0%)
  adding: testb/file 6.html (stored 0%)
  adding: testb/file 7.html (stored 0%)
  adding: testb/file 8.html (stored 0%)
  adding: testb/file 9.html (stored 0%)

使用unzip命令验证是否正确压缩:

(base) hniii98@ysyx:/tmp$ unzip -l Allhtml.zip 
Archive:  Allhtml.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  2024-09-05 11:54   testa/file 1.html
        0  2024-09-05 11:54   testa/file 2.html
        0  2024-09-05 11:54   testa/file 3.html
        0  2024-09-05 11:54   testa/file 4.html
        0  2024-09-05 11:54   testa/file 5.html
        0  2024-09-05 11:54   testa/file 6.html
        0  2024-09-05 11:54   testa/file 7.html
        0  2024-09-05 11:54   testa/file 8.html
        0  2024-09-05 11:54   testa/file 9.html
        0  2024-09-05 11:54   testb/file 1.html
        0  2024-09-05 11:54   testb/file 2.html
        0  2024-09-05 11:54   testb/file 3.html
        0  2024-09-05 11:54   testb/file 4.html
        0  2024-09-05 11:54   testb/file 5.html
        0  2024-09-05 11:54   testb/file 6.html
        0  2024-09-05 11:54   testb/file 7.html
        0  2024-09-05 11:54   testb/file 8.html
        0  2024-09-05 11:54   testb/file 9.html
---------                     -------
        0                     18 files

-print0 和 -0

        由于文件名中存在着空格,因此在分割find命令所得到的结果时无法用简单的空格实现。因此在find命令中加上-print0选项,使得每一个find得到的结果中使用空字符(null character \0)分隔文件名,确保文件名的正确分割。同时在xargs中添加-0选项做出对应的分割。

5.(进阶)编写一个命令或脚本递归的查找文件夹中最近使用的文件。更通用的做法,你可以按照最近的使用时间列出文件吗?

# m(odification) time of last 7*24 h
(base) hniii98@ysyx:/tmp$ sudo find / -mtime 7

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值