7

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.

2

2 Answers 2

12

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);
}
0
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.

2
  • 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, 2018 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, 2018 at 4:36

You must log in to answer this question.

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