编写一个脚本,以秒数作为参数,然后将会话保持一段时间(睡眠),然后显示从主目录中删除的文件列表。使用“date”显示睡眠前后的当前时间和日期。
#!/bin/bash
time_b=$(date)
(sleep 30
ls -all $HOME | grep -v "(cat tmp_file.txt )" | while read s
do
echo deleted file: $s
done
echo Time before: $time_b
echo Time after: $(date)
)
答案1
#!/bin/sh
snooze=$1
set -- "$HOME"/*
date +'Start: %F %T'
sleep "$snooze"
date +'End: %F %T'
for pathname do
if [ ! -e "$pathname" ]; then
printf 'Deleted from home: %s\n' "${pathname##*/}"
fi
done
该脚本采用第一个命令行参数 ,$1
并将其分配给变量snooze
。然后它获取主目录中所有文件和目录的名称(不包括隐藏名称)并将它们分配给位置参数($1
,$2
等)
在用户指定的睡眠时间之前,它会打印当前日期和时间。从睡眠中醒来后,它会再次打印日期和时间。
该for
循环遍历主目录中找到的原始名称并测试它们是否仍然存在。如果不再找到某个名称,则会打印该名称(并从其路径名中删除目录路径)。
就这些。
如果您只想检测删除常规文件(或常规文件的符号链接),那么您必须确保我们为主目录中的内容获取的路径名列表仅包含这些文件的路径名:
#!/bin/sh
snooze=$1
set --
for pathname in "$HOME"/*; do
if [ -f "$pathname" ]; then
set -- "$@" "$pathname"
fi
done
date +'Start: %F %T'
sleep "$snooze"
date +'End: %F %T'
for pathname do
if [ ! -e "$pathname" ]; then
printf 'Deleted from home: %s\n' "${pathname##*/}"
fi
done
在这里,不仅仅是保存全部从主目录可见的名称,我们循环遍历这些名称,只保存测试-f
正确的名称(常规文件和到常规文件的符号链接)。将跳过目录。脚本的其余部分与以前一样。
检测删除隐文件最简单的方法是切换到bash
(请注意,上述脚本是用 执行的/bin/sh
):
#!/bin/bash
shopt -s dotglob
snooze=$1
set --
for pathname in "$HOME"/*; do
if [ -f "$pathname" ]; then
set -- "$@" "$pathname"
fi
done
date +'Start: %F %T'
sleep "$snooze"
date +'End: %F %T'
for pathname do
if [ ! -e "$pathname" ]; then
printf 'Deleted from home: %s\n' "${pathname##*/}"
fi
done
请注意,唯一的区别是#!
- 行,表示现在应该由/bin/bash
解释器执行,以及在shell 中shopt -s dotglob
设置 shell 选项的命令。此 shell 选项使文件名通配模式(例如)匹配隐藏名称以及不以点开头的名称。dotglob
bash
*
另外还检测删除子目录听起来有点棘手,但事实并非如此:
#!/bin/bash
shopt -s dotglob globstar
snooze=$1
set --
for pathname in "$HOME"/**; do
if [ -f "$pathname" ]; then
set -- "$@" "$pathname"
fi
done
date +'Start: %F %T'
sleep "$snooze"
date +'End: %F %T'
for pathname do
if [ ! -e "$pathname" ]; then
printf 'Deleted from home: %s\n' "${pathname#$HOME/}"
fi
done
这里唯一的区别是我们还启用了该globstar
选项。这个 shell 选项使我们能够访问**
glob 模式,它与 类似 匹配*
,但也可以跨越/
路径名。因此该$HOME/**
模式将匹配一切在你的主目录下。
我还稍微修改了已删除路径名的打印,以包含比文件名更多的内容(因为它可能位于子目录中,并且很高兴看到什么子目录)。
答案2
#!/usr/bin/env bash
sleep_time=$1
time_a=$(date)
mapfile -t files_a < <(find "$HOME" -type f -maxdepth 1)
sleep "$sleep_time"
mapfile -t files_b < <(find "$HOME" -type f -maxdepth 1)
comm -23 <(printf '%s\n' "${files_a[@]}" | sort) <(printf '%s\n' "${files_b[@]}" | sort)
printf '%s\n' "We started at: $time_a" "We ended at: $(date)"
sleep_time=$1
- 已要求您提供睡眠时间的参数。你的论点将被表示为位置参数在你的脚本中。这意味着如果您调用它,
./script.sh 30
您的第一个位置参数将等于30
。
- 已要求您提供睡眠时间的参数。你的论点将被表示为位置参数在你的脚本中。这意味着如果您调用它,
time_a=$(date)
- 您已经在原始代码中弄清楚了这一点,但这将是我们用来显示我们开始时间的日期
mapfile -t files_a < <(find "$HOME" -type f -maxdepth 1)
- 这就是事情变得更加复杂的地方。我们需要构建之前的文件列表,以便将其与之后进行比较。在这里,我们使用映射文件来创建所述文件的数组。现在我们可以直接创建一个数组,但如果文件包含空格或换行符,这会给我们带来问题。 mapfile 会工作得更好一些。
find "$HOME" -type f -maxdepth 1
- 这将打印$HOME
目录中所有文件类型文件的列表(不会递归到任何子目录)
sleep "$sleep_time"
- 这是我们在指定时间睡觉的地方
mapfile -t files_b < <(find "$HOME" -type f -maxdepth 1)
- 我们正在创建睡眠后的第二个文件数组来进行比较
comm -23 <(printf '%s\n' "${files_a[@]}" | sort) <(printf '%s\n' "${files_b[@]}" | sort)
- 该
comm
实用程序读取两个文件并打印 3 列: (1) 行仅有的在文件 1 中,(2) 行仅有的in file2, (3) 两个文件中的行。由于我们只关心 file1 特有的行,因此我们使用参数-23
来抑制第 2 列和第 3 列。接下来,由于我们将文件存储在数组中,而不是我们使用的文件中流程替代将数组传递给comm
文件。
- 该
printf '%s\n' "We started at: $time_a" "We ended at: $(date)"
- 打印开始和结束时间。
答案3
这对我来说就像是大学作业。你的脚本没有意义,所以我只是尝试你说的。
- 编写一个脚本,以秒数作为参数,然后将会话保持一段时间(睡眠)
我假设您的 bash 脚本必须使用如下参数运行:./script 30
https://tiswww.case.edu/php/chet/bash/bashref.html#Shell-Parameters
- 之后显示从主目录中删除的文件列表。
for file in $HOME/*; do
# if it is a file
#save the value of $file on a log file placed not in your $HOME directory
#delete the file
done
http://mywiki.wooledge.org/BashPitfalls#for_f_in_.24.28ls_.2A.mp3.29
http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_07_01.html
- 使用“date”显示睡眠前后的当前时间和日期。这是不言自明的。
dateBefore="$(date)"
#sleep command here
dateAfter="$(date)"
echo "Date before sleep : $dateBefore"
echo "Date before after sleep : $dateBefore"
我尽力帮助您解决此问题,因此我可以假设您现在可以自己完成此脚本。如果你仍然做不到,手册页和谷歌是你的朋友:)