为什么我的循环有时不读取整行?

时间:2019-07-03 12:26:53

标签: bash loops scripting filepath

我一直在搜索这个问题几个小时,以前从未遇到过。我有一个脚本,可以为我的公司PRN创建教学视频的缩略图gif。当我运行它时,shell有时会忽略文件路径的一半,因此会失败。

这是在debian 9机器(bash)上。我尝试了多种写循环的方法,包括管道传输到文件(结果正确),然后将其读回循环(然后混合输出)。我已经尝试从脚本的第一行设置-x,这显然是shell本身的问题。结果也有所不同。有时我放入一个文件并得到30个字符,有时它只读取22个字符,但始终是失败的相同文件。 od -xa之间没有显示错误的字符。

这是我当前的循环起点,也是事情开始失败的地方,因此我不会费心发布其余部分。

PPATH="/home/pi/pmount/prntest"

find "$PPATH" -type f -iname "*.mp4" >tempfile

cat -v tempfile | while read i
do
makethumbs "$i"
echo "$i" >>test.txt
done

例如文件的路径为/home/pi/pmount/prntest/Security Training/Example #1.mp4

示例输出:

/prntest/Security Training/Example #1.mp4

urity Training/Example #1.mp4`

当然不能解析。有任何想法吗?我将非常感谢。

编辑:

必填信息:

Shell: /bin/bash 

GNU bash, Version 4.4.12(1)-release (x86_64-pc-linux-gnu) Copyright (C) 2016 Free Software Foundation, Inc. 

Linux 4.9.0-9-amd64 #1 SMP Debian 4.9.168-1+deb9u3 (2019-06-16) ``` 

2 个答案:

答案 0 :(得分:2)

最好输出空的$'\0'终止条目,而不是换行符$'\n'-print0命令的find选项可以做到这一点。

这是您的更正代码:

#!/usr/bin/env bash

PPATH=/home/pi/pmount/prntest

find "$PPATH" -type f -iname "*.mp4" -print0 >tempfile # write null-terminated strings to tempfile

while read -r -d '' i # -r do not expand globbing characters and -d '' use a null delimiter
do
  makethumbs "$i"
  echo "$i" >>test.txt
done <tempfile # inject the tempfile for the whole loop

答案 1 :(得分:1)

不必只写文件就可以立即读取文件。另外,为什么要cat -v

我会这样做:

find "$PPATH" -type f -iname "*.mp4" -print -exec makethumbs {} ';' | tee test.txt

好的,makethumbs是一个shell函数。仍然可以坚持这种方法:

export -f makethumbs 
find "$PPATH" -type f -iname "*.mp4" -print -exec bash -c '
    for file; do makethumbs "$file"; done
' _bash {} + | tee test.txt

使用-exec cmd {} +表单一次将多个文件传递给命令,以减少生成的bash shell的数量。

需要将函数导出到环境中,以便子外壳程序可以拾取它。

“ _ bash”自变量是必需的,因为在使用-c选项时传递自变量时,第一个自变量被视为$0