Linux 为什么cat会更改二进制文件的内容?
显然,在二进制文件上运行Linux 为什么cat会更改二进制文件的内容?,linux,bash,shell,unix,cat,Linux,Bash,Shell,Unix,Cat,显然,在二进制文件上运行cat并回显内容似乎不起作用。以下是我制作的简单脚本: #!/bin/sh CONTENTS=$(cat "$1") mv "$2" "$1" echo "$CONTENTS" > "$2" 出于某种原因,当我做这样的事情时,这似乎是一团糟: script first.pptx second.pptx 运行此操作后,新的first.pptx文件将正常打开,但新的second.pptx文件可能是无效格式或其他格式 为什么会发生这种情况?我可以做些什么来修复这种情
cat
并回显内容似乎不起作用。以下是我制作的简单脚本:
#!/bin/sh
CONTENTS=$(cat "$1")
mv "$2" "$1"
echo "$CONTENTS" > "$2"
出于某种原因,当我做这样的事情时,这似乎是一团糟:
script first.pptx second.pptx
运行此操作后,新的first.pptx
文件将正常打开,但新的second.pptx
文件可能是无效格式或其他格式
为什么会发生这种情况?我可以做些什么来修复这种情况?构造$(cat“$1”)
将在替换值之前删除文件中的所有尾随换行符(因此内容
将以此结束)
echo“$CONTENTS”
将截断第一个NUL字符处的内容,并追加换行符
因此,如果文件的结尾不是一个换行符,则内容将略有更改。如果它有任何NUL字符,它将被截断。这里有证据证明
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"
#/bin/bash
声明-a arr=()
{
而IFS=read-r-d;do
arr+=(“$s”)
完成
arr+=(“$s”)
}<尝试使用临时文件执行相同操作
cat < $file1 > $tempFile
cat < $file2 > $file1
cat < $tempFile > $file2
rm $tempFile
cat<$file1>$tempFile
cat<$file2>$file1
cat<$tempFile>$file2
rm$tempFile
是否不使用变量存储中间值<代码>mv$1 tmp;mv$2$1;mv tmp$2
?祝你好运。@不创建临时文件就可以这样做吗?嗯?为什么在cat
中会出现问题,而不是在C样式字符串中存储任意内容的问题(从本质上讲,C样式字符串以NUL结尾,因此无法存储文字NUL)?顺便说一句,您可以在shell数组中存储文字NUL内容,而不是标量值……请看下面的答案,并演示相同的内容。:)不是echo
在第一个NUL处截断内容——这发生在前面,因为具有文本NUL的内容根本不能存储在shell变量(那些是C字符串)中……此外,如果您阅读了echo
的POSIX规范,则传递带有任何反斜杠的字符串时的行为是完全未定义的。即使我们忽略了尾随的换行符,它也是一个完全不适合二进制数据的工具。