How do I get an equivalent of /dev/one in Linux
to zero fill a file. Instead of that I want to one fill a file. How do I do that? There is no /dev/one file, so how can I simulate that effect via on bash shell?
6 Answers 6
This should be much faster. Choose your blocksizes (or add counts) like you need at. Writing ones to a SSD-Disk till full with a blocksize of 99M gave me 350M/s write performance.
I confirm this is at least twice as fast as the accepted solution. However I didn’t notice any noticeable performance improvement from varying the blocksize (though there is a huge decrease of performance without the bs argument).
Thanks. I successfully used this modified command to one-fills my 2GB micro SD: tr ‘\0’ ‘\377’ < /dev/zero | pv | sudo dd bs=512K of=/dev/sdx with speed ~8MB/s. The command pv shows you how many bytes are done, and the speed. You may need to install it, but it's very useful.
@JohnnyWong: Adding status=progress to the arguments of dd gives a throughput measure output directly by dd .
Note that tr conversions depend on the locale — \377 may not be all 1 bits, for example on Mac with the en_US.UTF-8 locale, this encodes bfc3 bfc3 bfc3… . To get all ones consistently, you could set: env LC_ALL=C tr ‘\000’ ‘\377’
Substitute $’\377′ or $’\xFF’ if you want all the bits to be ones.
MacOS tr may complain about «Illegal byte sequence». Setting LC_CTYPE=C will prevent that. This version can also be used in Linux:
For others: on macOS you will need to set environment variable LANG=»C» to get tr to behave in the way that makes this command work
@MattSephton: I just tested it on MacOS Sierra and it works fine for me without changing LANG (mine is en_US.UTF-8).
Interesting. I was changing \00 to \xFF and was getting something other than \xFF until I used LANG=»C»
@MattSephton: Anything \x80 or above. Evidently it doesn’t like the 8th bit set unless LANG=C . For those that might not be aware, you can do that for just the environment of tr : dd if=<(yes $'\xFF' | LANG=C tr -d "\n") of=file count=1024 bs=1024 and it doesn't affect the general environment.
@ChrisStryczynski: Did you run it using sudo ? That’s one possible reason for that error. If so, then this is one way to make it work: sudo bash -c ‘dd if=<(yes $'\01' | tr -d "\n") of=file count=1024 bs=1024'
dd if=/dev/zero count=1024 bs=1024 | tr '\000' '\001' > file
Hmm, I guess it depends on what you want. This will fill a file with bytes of value 1 ( 01 01 01 01 . ). Using \377 gets you all bits set to 1 (so FF FF FF FF . ). Depends on the OP’s requirements.
pv /dev/zero |tr \\000 \\377 >targetfile
. where \377 is the octal representation of 255 (a byte with all bits set to one). Why tr only works with octal numbers, I don’t know — but be careful not to subconsciously translate this to 3FF.
The syntax for using tr is error prone. I recommend verifying that it is making the desired translation.
cat /dev/zero |tr \\000 \\377 |hexdump -C
Note: pv is a nice utility that replaces cat and adds a progress/rate display.
Note: If you are trying to fill an entire device, it’s probably better to avoid dd since that will slow things down (by a lot) if you don’t manually select an optimum bs value.
I created a device driver in my github. Installing it creates a file /dev/one that is writing only bits set to 1.
The c file called one.c (the only interesting part is in device_file_read ):
// File Driver to create a devince /dev/one like the /dev/zero #include #include #include #include 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);
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"
The instalation is long (3min) due to the driver signature enforcement. Froget this part if you disabled it in your UEFI.
- git clone https://github.com/tinmarino/dev_one.git DevOne && cd DevOne # Download
- make build # Compile
- make key # Generate key for signing
- sudo make sign # Sign driver module to permit MOK enforcement (security)
- sudo reboot now # Reboot and enable Mok
- A blue screen (MOK manager) will appear
- Choose «Enroll MOK»
- Choose «Continue»
- Choose «Yes» (when asked «Enroll the key»)
- Enter the password you gave at make sign
- Choose «Reboot» (again)
Команда dd и все, что с ней связано
В UNIX системах есть одна очень древняя команда, которая называется dd. Она предназначена для того, чтобы что-то куда-то копировать побайтово. На первый взгляд — ничего выдающегося, но если рассмотреть все возможности этого универсального инструмента, то можно выполнять довольно сложные операции без привлечения дополнительного ПО, например: выполнять резервную копию MBR, создавать дампы данных с различных накопителей, зеркалировать носители информации, восстанавливать из резервной копии данные на носители и многое другое, а, при совмещении возможностей dd и поддержке криптографических алгоритмов ядра Linux, можно даже создавать зашифрованные файлы, содержащие в себе целую файловую систему.
Опять же, в заметке я опишу самые часто используемые примеры использования команды, которые очень облегчают работу в UNIX системах.Начну с небольшого примера, наглядно иллюстрирующего основные параметры команды:
# dd if=/dev/urandom of=/dev/null bs=100M count=5
- if: указывает на источник, т.е. на то, откуда копируем. Указывается файл, который может быть как обычным файлом, так и файлом устройства.
- of: указывает на файл назначения. То же самое, писать можем как в обычный файл, так и напрямую в устройство.
- bs: количество байт, которые будут записаны за раз. Можно представлять этот аргумент как размер куска данные, которые будут записаны или прочитаны, а количество кусков регулируется уже следующим параметром.
- count: как раз то число, которое указывает: сколько кусочков будет скопировано.
Создание образа диска:
# dd if=/dev/cdrom of=image.iso
Команда будет считывать из устройства данные и записывать в файл до тех пор, пока не достигнет окончания устройства. Если диск битый, можно попробовать его прочитать, игнорируя ошибки чтения:
# dd if=/dev/cdrom of=image.iso conv=noerror
Параметр «conv» позволяет подключать несколько фильтров, применимых к потоку данных. Фильтр «noerror» как раз отключает остановку работы программы, когда наткнется на ошибку чтения. Таким образом, некоторые данные с диска все же можно будет прочитать. Точно таким образом я спас данные со своей флешки Corsair, которую погнули: подобрал подходящее положение, когда контакт есть, и сделал дамп файловой системы.
Подключить, кстати, такие образы можно при помощи команды mount с ключем «-o loop»:# mount -o loop image.iso /mnt/image
Если что-то не получается, процесс разбивается на 2 уровня:
# losetup -e /dev/loop0 image.iso
# mount /dev/loop0 /mnt/imageЕсли и так не работает, значит файловая система образа полетела.
Работа с носителями информации
Очень простое, хоть и не оптимальное решение клонирования жесткого диска:
# dd if=/dev/sda of=/dev/sdb bs=4096
Все то же побайтовой копирование с размером буфера 4 Кб. Минус способа в том, что при любой заполненности разделов копироваться будут все биты, что не выгодно при копировании разделов с маленькой заполненностью. Чтобы уменьшить время копирования при манипуляции с большими объемами данных, можно просто перенести MBR на новый носитель (я ниже опишу как), перечитать таблицу разделов ядра (при помощи того же fdisk), создать файловые системы и просто скопировать файлы (не забыв сохранить права доступа к файлам).
Как вариант, можно даже по расписанию делать бекап раздела по сети. Разрулив ключи ssh будет работать такая схема:
# dd if=/dev/DEVICE | ssh user@host «dd of=/home/user/DEVICE.img».
Когда-то читал исследование, согласно которому очень большая доля жестких дисков на барахолке подвергается восстановлению данных без привлечения чего-то специализированного, и содержит конфиденциальную информацию. Чтобы на носителе ничего нельзя было восстановить — можно забить его нулями:
# dd if=/dev/zero of=/dev/DEVICE
Думаю, понятно на что нужно заменить DEVICE. После проведения лекций по Linux, я очень тщательно стал следить за тем, что пишу.
Проверить можно тем же dd, но преобразовав данные в hex:# dd if=/dev/sda | hexdump -C
MBR расположена в первых 512 байтах жесткого диска, и состоит из таблицы разделов, загрузчика и пары доп. байт. Иногда, ее приходится бекапить, восстанавливать и т.д. Бекап выполняется так:
# dd if=/dev/sda of=mbr.img bs=512 count=1
# dd if=mbr.img of=/dev/sda
Причины этих махинаций с MBR могут быть разные, однако хочу рассказать одну особенность, взятую из опыта: после восстановления давней копии MBR, где один из разделов был ext3, а позже стал FAT и использовался Windows, раздел перестал видиться виндой. Причина — ID раздела, который хранится в MBR. Если UNIX монтирует файловые системы согласно суперблоку, то винды ориентируются на ID разделов из MBR. Поэтому всегда нужно проверять ID разделов при помощи fdisk, особенно если на компьютере есть винды.
При помощи dd можно генерировать файлы, а затем использовать их как контейнеры других файловых систем даже в зашифрованном виде. Технология следующая:
При помощи dd создается файл, забитый нулями (случайными числами забивать не рационально: долго и бессмысленно):# dd if=/dev/zero of=image.crypted bs=1M count=1000
Создался файл размером почти в гигабайт. Теперь нужно сделать этот файл блочным устройством и, при этом, пропустить его через механизм шифрования ядра linux. Я выберу алгоритм blowfish. Подгрузка модулей:
# modprobe cryptoloop
# modprobe blowfishАссоциация образа с блочным устройством со включенным шифрованием:
# losetup -e blowfish /dev/loop0 image.crypted
Команда запросит ввести пароль, который и будет ключем к образу. Если ключ введен не правильно, система не смонтируется. Можно будет заново создать данные в образе, используя новый ключ, но к старым данным доступа не будет.
Создаем файловую систему и монтируем:# mkfs.ext2 /dev/loop0
# mount /dev/loop0 /mnt/imageОбраз готов к записи данных. После завершения работы с ним, нужно не забыть его отмонтировать и отключить от блочного loop устройства:
# umount /dev/loop0
# losetup -d /dev/loop0Теперь шифрованный образ готов.
Основные идеи я расписал, однако множество задач, которые можно решить при помощи маленькой программки, имя которой состоит из двух букв, намного шире. Программа «dd» — яркий пример того, что IT’шники называют «UNIX way»: одна программа — часть механизма, выполняет исключительно свою задачу, и выполняет ее хорошо. В руках человека, который знает свое дело, которому свойственен не стандартный подход к решению задачи, такие маленькие программки помогут быстро и эффективно решать комплексные задачи, которые, на первый взгляд, должны решать крупные специализированные пакеты.