我有一个计算能力(fritzbox)和功能(busybox)有限的系统和一个网络摄像头,能够传输 JPG 文件。
现在我正在寻找一种方法(基于 shell 脚本)每 5 秒下载一次 JPG 文件,保存它们(这没有问题wget
)并稍后通过网络服务器流式传输它们。
我设置了一切,但遇到了一些问题:由于系统变得非常慢,一个文件夹中有这么多 JPG 文件(即使我将它们分成几个文件夹),我考虑将它们写入一个文件(echo
,cat
,... )并稍后再次提取它们(sed
, awk
)。
现在,shell 脚本不太适合处理二进制数据,因此“echo”和“cat”命令会失败,因为它们不会生成可读的 jpg 文件。
我将 JPG 文件下载wget
到临时文件或变量中。目前,我将cat
每个新的 JPG 保存到一个公共文件中,并用唯一的字符串(例如“--myboundary”)分隔,我会在没有换行符的情况下回显该字符串。
我现在如何从这个包含所有 JPG 的通用文件中提取单个 jpg?我尝试过awk
,但得到了一些糟糕的结果。
答案1
如果您可以重新开始,请使用tar
.它有一个“追加模式”,其中包含以下r
选项:
$ ls t.tar
ls: cannot access t.tar: No such file or directory
$ tar rvf t.tar t.c
t.c
$ tar rvf t.tar t.cpp
t.cpp
$ tar tf t.tar
t.c
t.cpp
(正如您所看到的,使用追加模式不必存在 tar 文件,因此它应该很容易用于您的情况。)
如果你没有完整的 GNU tar 实现,awk
应该能够使用类似的东西对你的合并文件进行排序(取自这堆栈溢出帖子):
awk -vRS="--myboundary" '{ print $0 > NR".jpg" }' yourfile
这将创建名为 、 等的文件1.jpg
。2.jpg
问题:它\n
在文件末尾添加了一个杂散符。
假设您有truncate
并且stat
在您的环境中,您可以使用以下方法修复这些文件:
truncate -s $(( $(stat -c %s 1.jpg) - 1 )) 1.jpg
如果你没有stat
,你将需要其他东西来找出文件名(解析ls
可能在这种情况下没问题,因为你知道文件名是正常的)。如果没有truncate
,您可以使用dd
, 或者可能使用head
或来实现这一点tail
。
或者您可以忽略尾随\n
,无论如何,图像很可能会正确显示。
演示:
$ cp orig.1.png blob
$ echo -n "HELLOHELLO" >> blob
$ cat orig.2.png >> blob
$ ls -l
total 36
-rw-r--r-- 1 test test 14916 Dec 30 19:42 blob
-rw-r--r-- 1 test test 5735 Dec 30 19:41 orig.1.png
-rw-r--r-- 1 test test 9171 Dec 30 19:41 orig.2.png
$ awk -vRS="HELLOHELLO" '{print $0 > "new."NR".png"}' blob
$ ls -l
total 56
-rw-r--r-- 1 test test 14916 Dec 30 19:42 blob
-rw-r--r-- 1 test test 5736 Dec 30 19:43 new.1.png
-rw-r--r-- 1 test test 9172 Dec 30 19:43 new.2.png
-rw-r--r-- 1 test test 5735 Dec 30 19:41 orig.1.png
-rw-r--r-- 1 test test 9171 Dec 30 19:41 orig.2.png
$ for i in new* ; do truncate -s $(( $(stat -c %s $i) - 1 )) $i ; done
$ ls -l
total 56
-rw-r--r-- 1 test test 14916 Dec 30 19:42 blob
-rw-r--r-- 1 test test 5735 Dec 30 19:43 new.1.png
-rw-r--r-- 1 test test 9171 Dec 30 19:43 new.2.png
-rw-r--r-- 1 test test 5735 Dec 30 19:41 orig.1.png
-rw-r--r-- 1 test test 9171 Dec 30 19:41 orig.2.png
$ md5sum *.png
70718d7b9e717206b4a8455ea32b51ed new.1.png
531099b9527f5fc2b623a3f724573ea9 new.2.png
70718d7b9e717206b4a8455ea32b51ed orig.1.png
531099b9527f5fc2b623a3f724573ea9 orig.2.png
答案2
您几乎正在尝试重新发明 tar 或类似的归档格式;不要指望手动执行操作会比使用现有工具更容易。
如果您坚持使用自定义边界(这是危险的,因为该边界可能自然出现在其中一个 jpeg 文件中),请使其以换行符开始和结束。这将有利于处理awk
。
我建议将每个文件分开,但将每个目录的文件数量限制为足够小的数量,以免影响性能。每 5 秒一个文件,日/小时/分钟的嵌套结构给出的最大分支为 366/60/20,这在性能方面应该是可以的。
如果您想使用存档,并且考虑到 Busybox tar 中缺少命令r
,您可以在文件系统中存储 N 个文件,然后定期使用现有文件进行存档并清理记录。例如,每 100 个文件归档一次:
set -- *
if [ $# -gt 100 ]; then
set ../archives/*.tar
eval "last=\${$#}"
last=${last%[!0-9]}; last=${last##[!0-9]}
tar cf ../archives/$((last+1)).tar -- *
rm -- *
fi