为什么这个脚本在使用 crontab 自动运行时会输出损坏的文件?

为什么这个脚本在使用 crontab 自动运行时会输出损坏的文件?

我有一个脚本可以扫描文件夹中的所有 .mp3 文件并创建索引。接下来等待5秒,否则无法正常工作。最后,它从歌曲名称中删除了不好的字符。

我使用 sudo crontab 自动运行它:

#!/bin/bash
#Creates index file.
find /var/www/html/uploads/Music/ -name '*.mp3' > /var/www/html/uploads/Music/songs.index | sleep 5s | sudo sed -i -e 's/\/var\/www\/html/\.\./g' /var/www/html/uploads/Music/songs.index

由于某种原因,当它通过 crontab 运行时,它会创建一个文件,该文件必须转换为文本并返回索引才能读取它。当您手动运行相同的脚本时,它工作正常。我缺少什么?

crontab 文件:

1 * * * * /home/aaeadmin/bin/midnightRun.bash

答案1

这是可能因为您在管道中运行命令。

管道的每个部分同时启动并与同一管道的其他部分同时运行。这意味着该find命令与该命令完全同时启动sed。只有通过管道传递的数据(从一个命令的标准输出到下一个命令的标准输入)才能同步不同的命令。

另请注意,您实际上并没有使用管道的管道方面。命令之间没有传递数据。

你的脚本最好写成

#!/bin/bash
#Creates index file.

find /var/www/html/uploads/Music/ -name '*.mp3' > /var/www/html/uploads/Music/songs.index

sed -i -e 's/\/var\/www\/html/\.\./g' /var/www/html/uploads/Music/songs.index

在这里,find命令将在命令开始之前完成执行sed。我还删除了该sudo命令,因为它显然不需要(如果find可以写入文件,则sed可以在没有 的情况下读取和修改它sudo)。

如果你发现你如果需要sudo写入songs.index,我建议您在属于具有写入目标目录权限的用户的 crontab 中运行此 cron 作业/var/www/html/uploads/Music

管道式解决方案是

#!/bin/sh
#Creates index file.

find /var/www/html/uploads/Music/ -name '*.mp3' |    
sed -e 's,^/var/www/html,..,' >/var/www/html/uploads/Music/songs.index

在这里,find写道直接地命令sed,并将命令的结果sed写入索引文件。来自findinto的数据(路径名)通信sed使两个进程保持同步,并且sed等待用于find在继续之前生成下一行输入(反之亦然;在尝试输出更多数据之前find会等待sed处理数据)。

我还使sed命令更易于阅读,并将正则表达式锚定到行的开头,并删除了g末尾不必要的标志。由于它现在从find命令中读取,我还删除了该-i选项(严格来说,该-e选项也可以删除)。

我改变的另一件事是线路#!。您没有使用任何bash特定功能,因此我们也可以使用(可能)更轻量级的 shell 来运行脚本。

如果您想将找到的文件的文件名写入索引,并将首字母/var/www/html替换为 ,..您也可以直接从以下位置执行此操作find

#!/bin/sh
#Creates index file.

find /var/www/html/uploads/Music/ -type f -name '*.mp3' -exec sh -c '
    for pathname do
        printf "../%s\n" "${pathname#/var/www/html/}"
    done' sh {} + >/var/www/html/uploads/Music/songs.index

这个find命令将找到名称与给定模式匹配的所有常规文件(即不是目录等)的路径名。对于批量的这些路径名,将调用一个简短的内联 shell 脚本。该脚本只是迭代当前批次的路径名并稍微修改后将其打印出来。

对路径名的修改是通过参数替换来完成的${pathname#/var/www/html/}。这删除/var/www/html/从 中的值开始的字符串$pathname。然后使用的格式printf字符串将确保这部分被替换为../.

也可以看看

相关内容