使用 dd 将同一文件多次写入一个文件

使用 dd 将同一文件多次写入一个文件

我正在尝试使用 dd 在驱动器上创建大型虚拟文件。我目前正在这样做:

#!/bin/bash
writeFile(){ #$1 - destination directory/filename, $2 - source filepath $3 - blocksize, $4 - blockcount $5 - log file name

if [ "$#" -ne 5 ]; then
    echo "Bad number of args - Should be 4, not $#"
    return 1;
fi

dest_filepath=$1
src_filepath=$2
block_size=$3
block_count=$4
log_file=$5

int_regex='^[0-9]+$' 

file_size=$(($block_size * $block_count))
src_file_size=`ls -l $src_filepath | awk '{print $5}'`
full_iter=0
while [[ $file_size -ge $src_file_size ]]; do
    file_size=$((file_size - $src_file_size))
    full_iter=$((full_iter + 1))
done

section_block_count=$(($src_file_size / $block_size))
echo $section_block_count $block_size
topping_off_block_count=$(($file_size / $block_size))

dest_dir=$(dirname $dest_filepath)
if [ -d "$dest_dir" ] && [ -r $src_filepath ] && [[ $block_size =~ $int_regex ]] && [[ $block_count =~ $int_regex ]]; then
    data_written=0
    for (( i=0 ; i < $full_iter ; i=$((i+1)) )); do
        (time dd of=$dest_filepath if=$src_filepath bs=$block_size count=$section_block_count seek=$data_written) >> $log_file 2>&1 #Output going to external file
        data_written=$(($data_written + $src_file_size +1 ))
        echo $data_written
    done

    if [[ $file_size -gt 0 ]]; then
        (time dd of=$dest_filepath if=$src_filepath bs=$block_size count=$topping_off_block_count seek=$data_written) >> $log_file 2>&1 & #Output going to external file
    fi
    return 0;
fi

return 1;   
}

但是,这是行不通的,因为它要么只写入一次src_filepath,要么多次写入文件的同一部分,我不知道如何找出差异。在这种特殊情况下,我正在做的是从 256MB 文件写入 4 次以创建单个 1GB 文件,但我想保持它通用,以便我可以写入任何大小。

目的是对硬盘驱动器进行碎片化,并测量 dd 的输出(特别是传输速率)及其所花费的时间。

我使用的是一个功能有限的嵌入式系统,操作系统是一个非常低版本的Linux,使用busybox。

如何更改它以便它写入正确大小的文件?

答案1

回复评论:不conv=notrunc截断dd,但不使其查找到末尾。 (它省略了O_TRUNC,但没有添加到系统调用O_APPENDopen(2))。

回答问题:如果您坚持使用dd而不是cat,那么让 shell 打开输出文件进行追加,并将 dd 写入其标准输出。

dd if=src bs=128k count=$count of=/dev/stdout >> dest 2>> log

另外,如果您尝试对驱动器进行碎片化,则可以进行大量fallocate(1)分配来使用空间,然后在驱动器接近满时开始使用 dd 。 util-linux 的fallocate 程序是一个简单的系统调用前端fallocate(2)

例如,xfs 将检测打开、追加模式,并在关闭后将其推测预分配的空间保留在 EOF 之外分配几秒钟。因此,在 XFS 上,重复追加到同一文件的循环不会产生与写入许多小文件一样多的碎片。

您使用的是嵌入式系统,所以我假设您没有使用 xfs。在这种情况下,使用相当智能的文件系统,您仍然可能会看到关闭/重新打开/写入更多内容时产生的碎片比您期望的要少。也许在每次写入之间进行同步,等待 FS 分配并写出所有数据,然后再让它知道还有更多数据即将到来。

相关内容