4

I am attempting to copy an Arch Linux ISO image directly to a USB drive. Previously, I have simply used either cp or dd to do this, such as:

sudo cp image.iso /dev/sdb

where /dev/sdb is the USB device. This has worked fine, but I want something that shows the progress while it is copying. I learned about the pv utility, which can show progress. However, I get permission denied whenever attempting to run the following:

sudo pv image.iso > /dev/sdb
bash: /dev/sdb: Permission denied

I thought that maybe it wasn't working because of an existing file system on the device, so I did:

sudo dd if=/dev/zero of=/dev/sdb bs=1G

to clear everything off the device, then retried. But I get the same error. What could be causing this? I'm pretty sure that I'm using pv correctly. I have tested using pv by copying the ISO to another location and it works:

sudo pv image.iso > test.iso

works fine. I am running these commands on a fully-updated x86-64 Arch Linux system.

NOTE: I am aware that dd also has progress state with the status=progress option, but this does not seem to work either.

New contributor
esotechnica is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
5
  • 3
    See How to run a command that involves redirecting or piping with sudo?. Note that pv has a -o (--output) modifier that should avoid the need for redirection in this particular case. Commented yesterday
  • Thanks, this solved the permission issue. Unfortunately pv appears to be useless in this case, it just immediately returns a status of 100% even though it continues copying for a couple of minutes afterwards! :( Commented yesterday
  • I guess you're just seeing the progress of filling the write cache ... Commented yesterday
  • 2
    but this does not seem to work either. – Try using bs=1M then instead. Setting it to 1G is extremely excessive and will mess with the progress indication. Commented yesterday
  • 2
    @esotechnica you probably want pv -Y for that kind of usage. Commented 12 hours ago

2 Answers 2

7

Your problem with

sudo pv image.iso > /dev/sdb
bash: /dev/sdb: Permission denied

is that > it is a redirect of the output of sudo and therefore runs as the original user, not as root.

You need to ensure that whatever is doing the write is also running as root.

For example:

sudo pv image.iso | sudo dd of=/dev/sdb

Now the write is being done by dd, which is running as root, so no issues.

There are various general ways to solve this problem, as it occurs regularly in shell scripting. For simple text, you may like:

sudo my_root_command | sudo tee path/to/output/file > /dev/null

... and there many other ways too. There are better ways to do what you're doing, as suggested by @forest, but the above is why you are getting permission denied.

New contributor
Roger Lucas is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
2
  • 1
    And if you're using dd anyway, you might as well just use sudo dd if=image.iso of=/dev/sdb status=progress bs=64K. (Using dd with the default bs=512 bytes is slow, making a system call for every half a KiB, much smaller than the sector size for modern devices so the kernel's block layer has to merge requests.) Commented 6 hours ago
  • 1
    Probably doesn't need sudo to read the image with pv, given that they probably already have access to the image, but otherwise good answer. Commented 5 hours ago
4

You cannot use redirection with sudo and expect unprivileged bash to be able to open a root-writable file for writing. See How to run a command that involves redirecting or piping with sudo?


You need to stop using such a large block size. Try this instead:

dd if=image.iso of=/dev/sdb bs=1M status=progress

In some situations, you can also improve performance by enabling direct I/O mode which bypasses the page cache. This will also increase accuracy of the progress report:

dd if=image.iso of=/dev/sdb bs=1M status=progress oflag=direct

Beware that using direct I/O takes all optimizations out of the kernel's hands, and thus block size can have a tremendous impact on performance. Try a few different block sizes.

4
  • Nope, it doesn't work. The progress doesn't print at all. I've posted a new question which better summarizes my problem. unix.stackexchange.com/questions/800242/… Commented yesterday
  • Even when you use bs=1M (not 1G) and oflag=direct? The reason it would show no progress without that is because it's being buffered almost instantly by the page cache, and then flushed at the very end. Commented yesterday
  • 1
    OK, so by itself bs=1M makes no difference. Adding oflag=direct fixes it! Thanks! Commented yesterday
  • 4
    The reason for this is that the file is read (almost instantly) into the page cache and dd only sees that. By using direct I/O, you're bypassing the page cache, so each megabyte is sent directly from the file to the drive. This can sometimes improve performance, but sometimes it reduces performance. However it does make sure that the page cache is kept out of the picture so that dd is able to monitor progress all by itself. Just note that the impact of the block size on performance matters much more when using direct I/O because the kernel is no longer optimizing writes. Commented yesterday

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.