首先,我在这方面相当缺乏经验,但我需要一个特定的 bash 脚本用于我的一个游戏服务器。该 bash 脚本应该只是确定特定文本文档的内容是否定期发生变化。
如果 30 秒内确实存在任何类型的变化,脚本应该执行以下操作:
echo "text file content is changing"
如果 30 秒内不存在任何变化,脚本应该执行:
echo "text file content is not changing"
当bash脚本判断内容发生变化之后,它应该不断重复自己。
编辑:谢谢大家的帮助!我还有一个担心,脚本是否会自动确定特定文件夹中最新创建/编辑的文本文件?这意味着,如果在脚本确定上一个文本文件时在该文件夹中创建了一个新的文本文件,它应该取消该过程并确定新的(最新)文件。
提前致谢! :-)
答案1
我使用/usr/bin/stat --format='%Y'
我的配置文件,每当“更改”时都会制作一个私人副本"%Y time of last data modification, seconds since Epoch
。这样,我不需要只阅读整个文件来检查修改时间。
无法运行的代码片段:
original="" # set the <config.file>
original_update=0 # time <config.file> was last modified
config="/var/tmp/${me}.$$.config" # my writable copy of config
...
function up-to-date () {
# updates configuration file if necessary
new_update="$(/usr/bin/stat --format='%Y' $original )"
if [[ "$new_update" -ne "$original_update" ]] ; then
if [[ $(countconfiglines "$original") -eq 0 ]] ; then
echo "Invalid configuration in $original" >&2
exit 4
else
/bin/cp --force "$original" "$config"
original_update="$new_update"
fi
fi
}
...
else
# watch for changes, record "%Y time of last modification,
# seconds since Epoch"
original_update="$(/usr/bin/stat --format='%Y' $original )"
# make a writeable copy for our use, and clean it up at the end
# unless $debug
[[ $debug -ne 0 ]] || trap "/bin/rm -f $config" EXIT
/bin/cp --force "$original" "$config"
fi
up-to-date
当我愿意解析一个新的配置文件时,我每次都会在主循环中调用它。
答案2
查看单个文件
使用文件校验和这里有一个可以帮助您的示例脚本。
#!/bin/bash
# do not put tabs before paths for second file through last file
files_to_check="/path/to/first/file
/path/to/second/file
/path/to/.../file"
delay=30
while true
do
while read path
do
[ ! -e "$path.sha256" ] && sha256sum "$path" > "$path.sha256"
status=$(sha256sum --quiet -c "$path.sha256" > /dev/null 2>&1 && echo "No change!" || (echo "File changed!" && sha256sum "$path" > "$path.sha256"))
[ "$status" == "No change!" ] && color="\e[0m" || color="\e[38;5;208m"
printf "$color[%s] %s: %s\e[0m\n" $(date +%Y%m%d.%H%M%S) "$path" "$status"
done <<< "$files_to_check"
sleep $delay
echo "-----------"
done
如果您只想递归检查整个目录,您可以将输出传递find /dir/to/check -type f
给 while 循环而不是文件列表。
上述脚本的输出如下所示
[20170413.095401] a: No change!
[20170413.095401] b: No change!
-----------
[20170413.095431] a: No change!
[20170413.095431] b: No change!
-----------
[20170413.095501] a: File changed!
[20170413.095501] b: No change!
扫描整个目录并观察文件的添加/删除/修改
该脚本将每 30 秒扫描一次整个目录(不包括运行扫描所需的时间),并将添加(绿色)、删除(红色)和更改(橙色)颜色标记。
#!/bin/bash
# do not put tabs before paths for second file through last file
dir_to_check="/path/to/directory"
delay=30
# please note that the time it takes to generate checksums will produce more time
# between loops than the actual delay
while true
do
while read path
do
[ ! -e "${path/.sha256/}" ] && printf "\e[38;5;196m%s\e[0m\n" "[$(date +%Y%m%d.%H%M%S)] File removed: ${path/.sha256/}" && rm "$path"
done <<< "$(find $dir_to_check -type f -iname "*\.sha256" | sort)"
while read path
do
if [ ! -e "$path.sha256" ]; then
printf "\e[38;5;046m%s\e[0m\n" "[$(date +%Y%m%d.%H%M%S)] New file found: $path (modified $(date --date="@$(stat --format="%Y" "$path")" +%Y%m%d.%H%M%S))"
sha256sum "$path" > "$path.sha256"
else
status=$(sha256sum --quiet -c "$path.sha256" > /dev/null 2>&1 && echo "No change!" || (echo "File changed! ($(date --date="@$(stat --format="%Y" "$path")" +%Y%m%d.%H%M%S))" && sha256sum "$path" > "$path.sha256"))
[ "$status" == "No change!" ] && color="\e[0m" || color="\e[38;5;208m"
printf "$color[%s] %s: %s\e[0m\n" $(date +%Y%m%d.%H%M%S) "$path" "$status"
fi
done <<< "$(find $dir_to_check -type f ! -iname "*\.sha256" | sort)"
sleep $delay
echo "-----------"
done
输出类似(抱歉,这里颜色没有转移)
[20170414.103126] /tmp/change/a: No change!
[20170414.103126] /tmp/change/b: No change!
[20170414.103126] /tmp/change/c: No change!
[20170414.103126] /tmp/change/run.sh: File changed! (20170414.103125)
-----------
...
-----------
[20170414.103156] File removed: /tmp/change/a
[20170414.103156] /tmp/change/b: No change!
[20170414.103156] /tmp/change/c: No change!
[20170414.103156] /tmp/change/run.sh: No change!
-----------
[20170414.103206] New file found: /tmp/change/a (modified 20170414.103200)
[20170414.103206] /tmp/change/b: No change!
[20170414.103206] /tmp/change/c: No change!
[20170414.103206] /tmp/change/run.sh: No change!