【问题标题】:How do I get an equivalent of /dev/one in Linux如何在 Linux 中获得 /dev/one 的等价物
【发布时间】:2023-03-28 10:43:01
【问题描述】:

你可以使用

dd if=/dev/zero of=file count=1024 bs=1024 

零填充文件。

我想要一个填充文件而不是那个。我该怎么做?

没有 /dev/one 文件,如何通过 bash shell 模拟这种效果?

【问题讨论】:

  • 写个C程序来做,应该很简单。

标签: linux file bash


【解决方案1】:
tr '\0' '\377' < /dev/zero | dd bs=64K of=/dev/sdx

这应该快得多。选择您需要的块大小(或添加计数)。以 99M 的块大小将它们写入 SSD 磁盘直到写满给了我 350M/s 的写入性能。

【讨论】:

  • 我确认这至少是公认解决方案的两倍。但是,我没有注意到改变块大小有任何明显的性能改进(尽管没有 bs 参数,性能会大幅下降)。
  • 谢谢。我成功地使用这个修改后的命令来填充我的 2GB micro SD:tr '\0' '\377' &lt; /dev/zero | pv | sudo dd bs=512K of=/dev/sdx,速度约为 8MB/s。命令pv 显示完成了多少字节,以及速度。您可能需要安装它,但它非常有用。
【解决方案2】:

试试这个:

dd if=<(yes $'\01' | tr -d "\n") of=file count=1024 bs=1024

如果您希望所有位都为 1,请替换 $'\377'$'\xFF'

【讨论】:

  • 对于其他人:在 macOS 上,您需要设置环境变量 LANG="C" 以使 tr 以使该命令工作的方式运行
  • @MattSephton:我刚刚在 MacOS Sierra 上对其进行了测试,它对我来说很好,无需更改 LANG(我的是 en_US.UTF-8)。
  • 有趣。在我使用 LANG="C" 之前,我将 \00 更改为 \xFF 并且得到了 \xFF 以外的其他内容
  • @MattSephton:\x80 或以上的任何内容。显然它不喜欢第 8 位设置,除非LANG=C。对于那些可能不知道的人,您可以只针对trdd if=&lt;(yes $'\xFF' | LANG=C tr -d "\n") of=file count=1024 bs=1024的环境这样做,它不会影响一般环境。
  • @ChrisStryczynski:您是否使用sudo 运行它?这是该错误的一个可能原因。如果是这样,那么这是使其工作的一种方法:sudo bash -c 'dd if=&lt;(yes $'\01' | tr -d "\n") of=file count=1024 bs=1024'
【解决方案3】:

好吧,你可以这样做:

dd if=/dev/zero count=1024 bs=1024 |
  tr '\000' '\001' > file

【讨论】:

  • 一个填充将是 '\377',不是吗?
  • 嗯,我想这取决于你想要什么。这将用值 1 (01 01 01 01 ...) 的字节填充文件。使用\377 会将所有 设置为1(所以FF FF FF FF ...)。取决于 OP 的要求。
【解决方案4】:
pv /dev/zero |tr \\000 \\377 >targetfile

...其中\377255 的八进制表示(所有位都设置为1 的字节)。为什么tr 只适用于八进制数字,我不知道——但请注意不要下意识地将其翻译为 3FF


使用tr 的语法容易出错。我建议验证它是否正在进行所需的翻译...

cat /dev/zero |tr \\000 \\377 |hexdump -C

注意:pv 是一个不错的实用程序,它取代了cat 并添加了进度/速率显示。

【讨论】:

  • 注意:如果您试图填满整个设备,最好避免使用dd,因为如果您不手动选择最佳@987654331,这会减慢速度(很多) @值。
  • 如果有足够的信息,pv 也会给出剩余时间的估计。
  • 当你在它的时候,也许前缀timenice
【解决方案5】:

我在github 中创建了一个设备驱动程序。安装它会创建一个文件/dev/one,它只写入设置为 1 的位。

名为 one.c 的 c 文件(唯一有趣的部分在 device_file_read):

// File Driver to create a devince /dev/one like the /dev/zero

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>

MODULE_LICENSE("GPL");

static int device_file_major_number = 0;
static const char device_name[] = "one";

static ssize_t device_file_read(
        struct file *file_ptr,
        char __user *user_buffer,
        size_t count,
        loff_t *position) {
    printk( KERN_NOTICE "One: Device file is read at offset = %i, read bytes count = %u\n" , (int)*position , (unsigned int)count );

    // Allocate Kernel buffer
    char* ptr = (char*) vmalloc(count);

    // Fill it with one, byte per byte
    // -- Note that byte is the smallest accesible data unit
    memset(ptr, 0xFF, count);

    char res = copy_to_user(user_buffer, ptr, count);
    if (res != 0){ return -EFAULT; }

    // Return number of byte read
    return count;
}

static struct file_operations simple_driver_fops = {
    .owner   = THIS_MODULE,
    .read    = device_file_read,
};

int register_device(void) {
    int res = 0;
    printk( KERN_NOTICE "One: register_device() is called.\n" );
    res = register_chrdev( 0, device_name, &simple_driver_fops );
    if( res < 0 ) {
        printk( KERN_WARNING "One:  can\'t register character device with error code = %i\n", res );
        return res;
    }
    device_file_major_number = res;
    printk( KERN_NOTICE "One: registered character device with major number = %i and minor numbers 0...255\n", device_file_major_number );
    return 0;
}

void unregister_device(void) {
    printk( KERN_NOTICE "One: unregister_device() is called\n" );
    if(device_file_major_number != 0) {
        unregister_chrdev(device_file_major_number, device_name);
    }
}

static int my_init(void) {
    register_device();
    return 0;
}

static void my_exit(void) {
    unregister_device();
    return;
}

// Declare register and unregister command
module_init(my_init);
module_exit(my_exit);

Makefile

TARGET_MODULE:=one

BUILDSYSTEM_DIR:=/lib/modules/$(shell uname -r)/build
PWD:=$(shell pwd)
obj-m := $(TARGET_MODULE).o
# See: https://stackoverflow.com/questions/15910064/how-to-compile-a-linux-kernel-module-using-std-gnu99
ccflags-y := -std=gnu99 -Wno-declaration-after-statement

build:
    # run kernel build system to make module
    $(MAKE) -C $(BUILDSYSTEM_DIR) M=$(PWD) modules

clean:
    # run kernel build system to cleanup in current directory
    $(MAKE) -C $(BUILDSYSTEM_DIR) M=$(PWD) clean
    rm -f MOK.priv MOK*.der

key:
    echo "Creating key"
    openssl req -new -x509 -newkey rsa:2048 -days 36500 -keyout MOK.priv -outform DER -out MOK.der -nodes -subj "/CN=TinmarinoUnsafe/"
    #
    echo "\e[31;1mPlease enter a password you will be asked for on reboot:\e[0m"
    mokutil --import MOK.der
    echo "\e[31;1mNow you must: 1/ reboot, 2/ Select Unroll MOK, 3/ Enter password you previously gave\e[0m"

sign:
    cp one.ko one.ko.bck
    /usr/src/linux-headers-$(shell uname -r)/scripts/sign-file sha256 MOK.priv MOK.der one.ko

load:
    insmod ./$(TARGET_MODULE).ko

unload:
    rmmod ./$(TARGET_MODULE).ko

create:
    mknod /dev/one c $(shell cat /proc/devices | grep one$ | cut -d ' ' -f1) 0

delete:
    rm /dev/one

test:
    [ "$(shell xxd -p -l 10 /dev/one)" = "ffffffffffffffffffff" ] \
        && echo "\e[32mSUCCESS\e[0m" \
        || echo "\e[31mFAILED\e[0m"

由于驱动程序签名强制执行,安装时间较长(3 分钟)。如果您在 UEFI 中禁用它,请忽略此部分。

  1. git clone https://github.com/tinmarino/dev_one.git DevOne &amp;&amp; cd DevOne # Download
  2. make build # Compile
  3. make key # Generate key for signing
  4. sudo make sign # Sign driver module to permit MOK enforcement (security)
  5. sudo reboot now # Reboot and enable Mok
    1. 会出现蓝屏(MOK 管理器)
    2. 选择“注册 MOK”
    3. 选择“继续”
    4. 选择“是”(当询问“注册密钥”时)
    5. 输入您在make sign 提供的密码
    6. 选择“重新启动”(再次)
  6. sudo make load # Load
  7. sudo make device # Create /dev/one
  8. make test # Test if all is ok

【讨论】:

    【解决方案6】:

    您可以在没有特殊设备的情况下模拟/dev/one,使用 FIFO + printf(循环;慢速)或yes(快速):

    mkfifo ddfifo
    dd if=ddfifo of=<file> iflag=fullblock count=1024 bs=1024 status=progress & while printf '\1'; do printf '\1'; done > ddfifo
    

    或者:

    mkfifo ddfifo
    dd if=ddfifo of=<file> iflag=fullblock count=1024 bs=1024 status=progress & yes "" | tr '\n' '\1' > ddfifo
    

    如果您想要所有位都设置为 1 的字节,请将 '\1' 交换为 '\377'

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-09-08
      • 2014-06-24
      • 2021-04-09
      • 1970-01-01
      • 2011-01-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多