Bash 在一个监视文件夹中新文件的小脚本中,该脚本似乎找到了错误的文件
我正在使用此脚本监视正在创建的新Bash 在一个监视文件夹中新文件的小脚本中,该脚本似乎找到了错误的文件,bash,inotify,Bash,Inotify,我正在使用此脚本监视正在创建的新.bin文件的下载文件夹。然而,它似乎不起作用。如果我删除了grep,我可以让它复制下载文件夹中创建的任何文件,但是grep不起作用。我怀疑问题在于我如何比较这两个值,但我真的不知道该怎么做 #!/bin/sh downloadDir="$HOME/Downloads/" mbedDir="/media/mbed" inotifywait -m --format %f -e create $downloadDir -q | \ while read line;
.bin
文件的下载文件夹。然而,它似乎不起作用。如果我删除了grep,我可以让它复制下载文件夹中创建的任何文件,但是grep不起作用。我怀疑问题在于我如何比较这两个值,但我真的不知道该怎么做
#!/bin/sh
downloadDir="$HOME/Downloads/"
mbedDir="/media/mbed"
inotifywait -m --format %f -e create $downloadDir -q | \
while read line; do
if [ $(ls $downloadDir -a1 | grep '[^.].*bin' | head -1) == $line ]; then
cp "$downloadDir/$line" "$mbedDir/$line"
fi
done
ls$downloadDir-a1 | grep'[^.].*bin'| head-1是错误的方法。要了解原因,假设您在下载目录中有名为
a.txt
和b.bin
的文件,然后添加了c.bin
inotifywait
将打印c.bin
,ls
将打印a.txt\nb.bin\nc.bin
(使用实际换行符,而不是\n),grep
将其精简为b.bin\nc.bin
,head
将删除除第一行之外的所有内容,这将与c.bin
不匹配。您需要检查$line
,查看它是否以.bin
结尾,而不是扫描目录列表。我将为您提供三种方法:
第一个选项,使用grep检查$line
,而不是列表:
if echo "$line" | grep -q '[.]bin$'; then
请注意,我正在使用-q
选项来抑制grep的输出,而只是让if命令检查其退出状态(如果找到匹配项,则检查成功,否则检查失败)。此外,RE被锚定到行的末尾,句点在括号中,因此它将只匹配实际的句点(通常,正则表达式中的
匹配任何单个字符)<代码>\.bin$也可以在这里使用
第二个选项,使用shell编辑变量内容的功能,查看$line
是否以.bin
结尾:
if [ "${line%.bin}" != "$line" ]; then
“${line%.bin}”
部分给出了$line的值,如果有,.bin
则从末尾修剪。如果这与$line
本身不同,则$line
必须以.bin
结尾
第三个选项,使用bash的[[]]
表达式直接进行模式匹配:
if [[ "$line" == *.bin ]]; then
这是(IMHO)最简单、最清晰的一个,但它只在bash中有效(即,您必须使用#!/bin/bash
启动脚本)
其他注意事项:为了避免文件名中可能出现的空格和反斜杠问题,请在IFS=read-r行时使用;执行
并虔诚地遵循@Sheller关于双引号的建议
另外,我对inotifywait不是很熟悉,但是AIUI的-e create
选项会在创建文件时通知您,而不是在完全写出文件内容时通知您。根据时间的不同,您可能会复制部分写入的文件
最后,您不需要检查重复的文件名。如果下载名为foo.bin
的文件,它会被复制,删除原始文件,然后下载名为foo.bin
的其他文件,会发生什么情况。现在的脚本将以静默方式覆盖第一个foo.bin
。如果这不是您想要的,您应该添加以下内容:
if [ ! -e "$mbedDir/$line" ]; then
cp "$downloadDir/$line" "$mbedDir/$line"
elif ! cmp -s "$downloadDir/$line" "$mbedDir/$line"; then
echo "Eeek, a duplicate filename!" >&2
# or possibly something more constructive than that...
fi
我不清楚它应该做什么。比较的目的是什么?如前所述,它似乎只复制包含“bin”的第一个(按字母顺序排列)文件(不一定以“bin”结尾,因为grep模式没有锚定到行的末尾)。事情,1。始终将未知性质的变量用db引号括起来,即,
“$line”
,如果在$line
的值中有一个空格,则可能会破坏某些内容,2。打开shell调试,即while循环上方的set-vx
。然后您将看到每一行/代码块,然后是分配给每个变量的值。然后很容易看出这些失败的地方。如果您不能理解它,请编辑您的帖子以包含相关调试输出。祝你好运。@GordonDavisson比较的目的是只移动与某个正则表达式匹配的文件,尽管我确实忘记了锚定该正则表达式。我不知道如何使inotify只移动符合模式的东西。