6

Is there a command that you can run in a shell script that would detect if the CD tray is open or closed, and return 1 or 0 depending on whether it was (or something easy to interpret)?

Currently, I am executing the open command, and timing how long it takes to execute. If it is almost instant, it is open. If it takes time, it was open and is now closed.

I would like a method that doesn't involve changing the current state - just detecting it.

10

I found a nice little solution here. The C code below, minimally changed from the linked site, will return an exit code of 0 if the tray is open and 1 if it is not.

So, save this code as something (e.g. foo.c) and compile it with this command:

gcc -o trayopen foo.c

Then, copy the compiled executable, trayopen to /usr/bin:

sudo cp trayopen /usr/bin

You should no be able to do things like

trayopen /dev/sr0 && echo closed

Or, more complete:

#!/bin/sh
if trayopen /dev/sr0
then
    echo "Tray is open."
else
    echo "Tray is closed."
fi

The code:

#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/cdrom.h>

int main(int argc,char **argv) {
  int cdrom;
  int status=1;

  if (! argv[1] ){
    printf("Usage : trayopen [device]\n");
    printf("Result: Returns a 0 if the tray was open and 1 if it was closed\n");
    exit(2);
  }

  if ((cdrom = open(argv[1],O_RDONLY | O_NONBLOCK)) < 0) {
    printf("Unable to open device %s. Provide a device name (/dev/sr0, /dev/cdrom) as a parameter.\n",argv[1]);
    exit(2);
  }
  /* Check CD tray status */
  if (ioctl(cdrom,CDROM_DRIVE_STATUS) == CDS_TRAY_OPEN) {
    status=0;
  }

  close(cdrom);
  exit(status);
}
4

Based on @terdon's C code, I wrote a version in Python:

#!/usr/bin/python
import os, fcntl, CDROM, sys

def drive_status(drive):
  fd = os.open(drive, os.O_RDONLY | os.O_NONBLOCK)
  rv = fcntl.ioctl(fd, CDROM.CDROM_DRIVE_STATUS)
  os.close(fd)
  return rv

sys.exit(drive_status(sys.argv[1]) != CDROM.CDS_TRAY_OPEN)

Clearly, it could use some love for comments and cmdline argument handling, but if you need a Python version... this will work.

Also note that the CDROM module may be Linux-specific, and that not all drives support querying (eg. the ioctl() will return CDS_NO_INFO).

There are other CDROM.CDS_* constants that provide helpful variants. In particular, CDS_DISK_OK will tell you if the tray is closed and has a disk present.

  • 1
    Note for Python 3.6: "The undocumented IN, CDROM, DLFCN, TYPES, CDIO, and STROPTS modules have been removed. They had been available in the platform specific Lib/plat-*/ directories, but were chronically out of date, inconsistently available across platforms, and unmaintained." – muru Apr 7 '18 at 2:19
  • Thanks for the edit, and the Python 3.6 note, @muru ... if CDROM.py is not available, then the constants can be found at: github.com/torvalds/linux/blob/master/include/uapi/linux/… – gstein Apr 7 '18 at 4:36

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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