I want to prevent my hard drive, an internal drive externally attached via USB dock, from spinning down. I don't see any way to adjust APM through hdparm, so I'm assuming it's limited by the firmware of the dock. This spins up the drive:

sudo dd if=/dev/sdc of=/dev/null count=1 skip=$RANDOM

But when I put the same thing in crontab via

sudo crontab -e


* * * * * dd if=/dev/sdc of=/dev/null count=1 skip=$RANDOM

nothing happens. Yes, I did check whether the drive is at /dev/sdc. I don't know if this info is relevant, but I've edited the crontab several times, and in each time, it suggested to save in a different file by default, which I followed. I'm not sure if this is the correct usage of skip=$RANDOM to read from a random block to prevent reading from cache.

Also, how can I make sure I target the correct drive persistently across several boot-ups or other orders of plugging in other devices, rather than targeting whatever ends up being /dev/sdc? I'm thinking something like

dd if=(findmnt -rn -S UUID=number_from_blkid -o SOURCE) of/dev/null count=1 skip=$RANDOM

but I don't know how to nest the return of the parenthetical statement into the outer statement. And even if I could, it would return /dev/sdX2, where X is whatever letter it happens to be and 2 is the only usable partition. The other is Windows reserved. This is less elegant than plain sdX.

  • AFAIK $RANDOM is a bashism whereas cron runs jobs in sh by default - are you sure it isn't just returning empty? – steeldriver Nov 15 '16 at 2:56
  • @steeldriver , I'm new to bash; got into it only due to this problem. I know that if I use the dd command outside of crontab, it will cause the drive to spin back up, even after the fact that I've added the same command to crontab. But this answer suggests it works. – CodeBricks Nov 15 '16 at 3:01
  • 1
    But that answer explicitly uses bash i.e. bash -c 'dd if=/dev/sda of=/dev/null count=1 skip=$RANDOM' whereas yours uses the default cron shell – steeldriver Nov 15 '16 at 3:04
  • @steeldriver , You're right. Prepending bash -c to the rest did the trick. Now, how can I do this by UUID rather than /dev/sdX? I'm basing my findmnt usage on this other answer and I get the UUID from sudo blkid. – CodeBricks Nov 15 '16 at 3:10

The problems

  1. It runs using the shell /bin/sh, not /bin/bash, so $RANDOM probably doesn't work
  2. Unless you set the PATH within your crontab file, it won't know where things like dd (or in the solution below, bash) are located
  3. If you want to do it using UUIDs, a much simpler way is to use /dev/disk/by-uuid/THE-UUID

The solution

  1. Find out the device file under /dev/disk/by-uuid by looking it up and checking that you don't get any errors with dd (replace THE-UUID with the actual UUID):

    ls -alF /dev/disk/by-uuid
    sudo dd if=/dev/disk/by-uuid/THE-UUID of=/dev/null count=1 skip=$RANDOM
  2. Edit root's crontab to (replace THE-UUID with the actual UUID):

    * * * * * /bin/bash -c 'dd if=/dev/disk/by-uuid/THE-UUID of=/dev/null count=1 skip=$RANDOM'
  • I have to wait out the firmware's idle-time-limit to spin down, to see if this doesn't spin down. The USB docked drive partition's UUID is alphanumeric but not dash-separated like that of my internally connected hard drive's partitions. In this answer, the example's UUID is dash-separated. Is this going to be a problem? – CodeBricks Nov 15 '16 at 3:53
  • 1
    I think NTFS drives (and perhaps other file systems too) are alphanumeric without dashes. See the UsingUUID page for an example of that happening. – Chai T. Rex Nov 15 '16 at 4:10
  • When I do your first step to see that I don't get any errors, the output shows it writes 512 bytes. But this is an advanced format 4 KiB sector drive. Is this a problem? Should I include bs=4096 right before the count=1? – CodeBricks Nov 15 '16 at 4:14
  • 1
    I don't think you'll need it because reading only 512 bytes at a time is supported just fine by dd and by drives, even if the sector size is different. What will happen is that, if the drive only supports 4096-byte reads, Linux will read in that and hand the first 512 bytes over to dd, so you effectively get the right behavior for free. – Chai T. Rex Nov 15 '16 at 4:20
  • Oh, I see. And I meant to say "reads 512 bytes from the hard drive" instead of "writes 512 bytes" in my previous comment (but I presume it does write to /dev/null), but you got my meaning. I was just basing my comment off of the terminal output that prints 512 bytes (512 B) copied. – CodeBricks Nov 15 '16 at 4:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.