显然,在二进制文件上运行cat
并回显内容似乎不起作用。这是我制作的简单脚本:
#!/bin/sh
CONTENTS=$(cat "$1")
mv "$2" "$1"
echo "$CONTENTS" > "$2"
出于某种原因,当我做这样的事情时,这似乎搞得一团糟:
script first.pptx second.pptx
运行此文件后,新的first.pptx
文件打开正常,但新second.pptx
文件的格式可能无效。
为什么会发生这种情况,我该怎么做才能解决这个问题?
答案 0 :(得分:4)
构造$(cat "$1")
将取代文件中的任何尾随换行符,然后替换该值(以便CONTENTS
将最终得到的结果)。
echo "$CONTENTS"
将截断第一个NUL字符的内容,并附加换行符。
因此,如果文件没有以一个换行符结尾,则内容将稍微改变。如果它有任何NUL字符,它将被截断。
答案 1 :(得分:3)
此处有cat
不更改值内容的证据,以及您实际尝试实施的脚本,实际上没有实际价值可以用bash编写:
#!/bin/bash
declare -a arr=( )
{
while IFS= read -r -d '' s; do
arr+=( "$s" )
done
arr+=( "$s" )
} < <(cat "$1") ## aside: this would be more efficiently just <"$1" without the cat
mv "$2" "$1"
{
printf '%s\0' "${arr[@]:0:${#arr[@]}-1}"
printf '%s' "${arr[@]:${#arr[@]}-1}"
} >"$2"
现在,这是如何工作的?
arr
是一个shell数组;每个元素都是一个C字符串。while IFS= read -r -d '' s
以递增方式将输入文件中的NUL分隔字符串读入s
。它只返回true,而这些字符串是NUL终止的;如果字符串不存在NUL终止符,则仍会填充变量s
,但read
命令返回false。 [有关while read
成语的更多信息,请参阅BashFAQ #001。printf '%s\0' ...
在格式字符串(在...
区域中)后跟NUL分隔符后发出每个参数。跳过第一个${#arr[@]}
后,arr
扩展为数组${arrayname[@]:SEEK:COUNT}
中的条目数,COUNT
扩展为数组arrayname
中的SEEK
项} items;因此,${arr[@]:0:${#arr[@]}-1}
扩展到数组arr
中除最后一项之外的所有项目,然后打印这些项目后跟一个NUL。printf
在最后一个NUL之后发出尾随内容 - 来自最后一个数组条目。如果运行此命令,您将观察到输入文件的md5sums交换,即使它们是包含NUL值的二进制文件。因此,您的问题的前提是错误的:cat
不更改二进制文件的内容。
答案 2 :(得分:0)
尝试使用临时文件执行相同操作。
cat < $file1 > $tempFile
cat < $file2 > $file1
cat < $tempFile > $file2
rm $tempFile