我在 SO 中遵循了几个线程将文件从一个目录复制到另一个目录。我正在使用 inotifywait 来达到我的目的,它对于除一种场景之外的所有场景都完美工作。它还复制以 DOT 前缀(例如 .tmp.swp)开头的文件,这是我不想要的。
我尝试了这个,但这甚至导致带有-json
后缀的文件无法被复制。我不想.tmp.abcd-json
被复制。如果我在&&
复制所有内容后删除检查,包括.tmp.abcd-json
:
这些是该目录的一些内容。这些.tmp
是不需要的,但并不总是保证它们总是以.tmp
.我见过其他文件.
随机以前缀开头,也需要忽略:-
abcd-json
.tmp.abcd-json
#!/bin/sh
dir=/var/lib/docker/containers
target=/var/log/splunkf
inotifywait -m -r "$dir" --format '%w%f' -e create -e modify \
| while read file;
do
if [[ $file == "-json"* ]] && [[ $file != "."* ]];
then
echo Copying $file to $target
cp -- "$file" "$target";
else
echo NOT Copying $file to $target
fi
done
答案1
您可以匹配RegEx
for 文件不是dot
从您的情况开始if
:
while read file;
do
f="$(basename -- $file)"
if ! [[ "$f" =~ ^\. ]];
then
echo Copying $file to $target
cp -- "$file" "$target";
else
echo NOT Copying $file to $target
fi
答案2
您的代码的主要问题不是在[[ ... ]]
.事实上,您获得的字符串$file
是一个路径名,在其开头包含一个目录路径,即,只有当目录路径以点开头时,该模式.*
才会匹配它。$dir
/bin/sh
您似乎还使用而不是 with运行脚本bash
,因此您不一定期望任何[[ ... ]]
测试都能工作。
要排除 匹配的文件名模式inotifywait
,请使用--exclude 'PATTERN'
.例如:
inotifywait -m -r --format '%w%f' -e create -e modify \
--exclude '/\.[^/]*$' "$dir"
此处使用的模式--exclude
匹配以点开头的文件名结尾的任何路径名。这些不会被报道inotifywait
。
当使用--exclude
with时inotifywait
,你的代码会折叠成
#!/bin/sh
dir=/var/lib/docker/containers
target=/var/log/splunkf
inotifywait -m -r --format '%w%f' -e create -e modify \
--exclude '/\.[^/]*$' "$dir" |
xargs -I {} cp -- {} "$target"
这显然假设没有文件名包含换行符。
bash
您想使用带有显式测试和诊断输出的循环吗,您可以使用
#!/bin/bash
dir=/var/lib/docker/containers
target=/var/log/splunkf
inotifywait -m -r --format '%w%f' -e create -e modify "$dir" |
while IFS= read -r pathname; do
if [[ ${pathname##*/} == .* ]]; then
printf 'Not copying "%s"\n' "$pathname" >&2
else
printf 'Copying "%s" to "%s"\n' "$pathname" "$target" >&2
cp -- "$pathname" "$target"
fi
done
注意使用IFS= read -r
.这是为了防止从文件名中去除两侧的空格并避免解释反斜杠序列(请参阅理解“IFS=读取-r行”)。
有了/bin/sh
,你会做
#!/bin/sh
dir=/var/lib/docker/containers
target=/var/log/splunkf
inotifywait -m -r --format '%w%f' -e create -e modify "$dir" |
while IFS= read -r pathname; do
case ${pathname##*/} in
.*)
printf 'Not copying "%s"\n' "$pathname" >&2
;;
*)
printf 'Copying "%s" to "%s"\n' "$pathname" "$target" >&2
cp -- "$pathname" "$target"
esac
done