-3

I'm trying to create a large random file on a ramdisk, in order to do some tests. I've created the ramdisk and my starting file (from /dev/urandom) without much trouble, but I'm having trouble increasing it's size (I was hoping I could just cat it into itself to double it up until the disk was full), and I'm unsure why. I'm hoping someone can tell me what I'm overlooking.

First, the file is definitely there:

$ ls -la /mnt/ramdisk/ramfile
-rw-r--r-- 1 root root 163840 Nov 22 11:07 /mnt/ramdisk/ramfile

Second, I try to use cat to double it's size, which fails:

$ sudo -s "cat /mnt/ramdisk/ramfile >> /mnt/ramdisk/ramfile"
/bin/bash: cat /mnt/ramdisk/ramfile >> /mnt/ramdisk/ramfile: No such file or directory

So I guess I'm misunderstanding something here, because I would expect that to work. I also tried catting the starting file twice to another file, but I got a similar error.

In case it's relevent, I created the file as follows:

sudo dd if=/dev/urandom of=/mnt/ramdisk/ramfile bs=16384 count=10

The reason I want to do this, I found urandom to be quite slow to read from (even on a massively overpowered server) and I want to ensure that the read speed from this random file isn't a bottleneck.

EDIT:

Versions-

GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)
cat (GNU coreutils) 8.21
Ubuntu 14.04 x86_64
2
  • I think you should read this, though I suspect it will simply lead you to another question. Nov 22, 2015 at 11:32
  • @MichaelHampton, thanks I read that, but it doesn't help answer my question, as that command has to be in quotes. In my script the command actually runs like so: sudo -s "cat $TESTFILE/ramfile > $TESTFILE/ramfile" Perhaps you could explain?
    – Rumbles
    Nov 22, 2015 at 11:45

3 Answers 3

2

There are two distinct problems with the command you attempted:

First, you can only pass a simple command to sudo via the -s option. In order to run a command line with I/O redirections you have to explicitly invoke a shell, like:

sudo bash -c "cat /mnt/ramdisk/ramfile >> /mnt/ramdisk/ramfile"

This will fix the error message you reported but lead to another one:

cat: /mnt/ramdisk/ramfile: input file is output file

Which exposes the second problem: cat is programmed to prevent exactly that which you are asking it to do, namely to append a file to itself. You can fool it by inserting a second cat into the pipeline, putting the first one off the track:

sudo bash -c "cat /mnt/ramdisk/ramfile | cat >> /mnt/ramdisk/ramfile"

Note that the behaviour of this command will depend on the initial size of the file /mnt/ramdisk/ramfile. If the file is small enough to fit into the buffer of the cat command it will be appended to itself just once, doubling its size. If it is bigger than the sum of all buffers in the pipeline it will be endlessly appended to itself again and again until the disk is filled. If its size lies between those two limits the behaviour is not deterministic.

4
  • Your last command will only work as intended for small files. For a large file it will just keep appending data.
    – kasperd
    Nov 25, 2015 at 11:24
  • You are right of course. However the question stated the intention to fill the disk, so the latter (just keep appending data) actually seems to be what the author wanted. Nov 26, 2015 at 9:24
  • And the subject says "trying to double the size", so I guess either behavior would be usable after all.
    – kasperd
    Nov 26, 2015 at 9:27
  • I'll amend my answer to state this more clearly. Nov 26, 2015 at 9:33
1

Please note: I have read your question carefully and answered it as stated. If you have other questions/issues that you have not stated then they are exatly that unstated and therefore unanswerable.

The problem here is that you are trying to open a file called exactly this

cat /mnt/ramdisk/ramfile >> /mnt/ramdisk/ramfile

and bash cannot find it. This is being caused because you are quoting the whole and so far as bash is concerned this is just a command line argument for it to execute.

So this is fairly easily solved

cat /mnt/ramdisk/ramfile >> /mnt/ramdisk/ramfile

Unfortunately this wont work as cat is smart

cat: /mnt/ramdisk/ramfile: input file is output file

With cat you an take multiple inputs and append them to an output

cat  /mnt/ramdisk/ramfile /mnt/ramdisk/ramfile >/mnt/ramdisk/ramfile.out

would make a ramfile.out that was two copies of ramfile.

You're also doing this as root via sudo. One other thing you need to be aware of is that the target of output redirection is opened using the original user's security context

sudo cat /mnt/ramdisk/ramfile /mnt/ramdisk/ramfile > /mnt/ramdisk/ramfile.out
-bash: /mnt/ramdisk/ramfile.out: Permission denied

So you need to ensure that the user you are sudoing from has suitable write permissions on the target file.

0

You can't copy a file on to itself. However, you can accomplish what you want with any of the following.

sudo cat $TESTFILE/ramfile $TESTFILE/ramfile > $TESTFILE/ramfile2; mv  $TESTFILE/ramfile2 $TESTFILE/ramfile

or

sudo bash -c "cat $TESTFILE/ramfile $TESTFILE/ramfile > $TESTFILE/ramfile2; mv  $TESTFILE/ramfile2 $TESTFILE/ramfile"
1
  • Thanks, I'm aware I can do this, but this won't do what I want, I am trying to fill this ramdisk, which is exactly what this version of cat seems to avoid doing by having this safety check. This technique won't allow me to fill the disk as there will always be some space left over... I probably need to use 2 ramdisks
    – Rumbles
    Nov 22, 2015 at 12:29

Not the answer you're looking for? Browse other questions tagged .