web-dev-qa-db-ja.com

ドライブにCD-ROMがあるかどうかを検出する方法

CD-ROMデバイスを知っています(/dev/sr0)しかし、ドライブが空であるかどうか、またはディスクがそこにあるかどうかをスクリプトからどのように検出できますか?

5
Aaron Digulla

コマンドblkidを使用すると、ブロックデバイスに関する情報を取得できます。

[root@Arch32-vm ~]# blkid /dev/sr0
/dev/sr0: UUID="2013-05-31-23-04-19-00" LABEL="Arch_201306" TYPE="iso9660" PTTYPE="dos"
[root@Arch32-vm ~]# echo $?
0

ディスクを削除すると、出力が得られず、終了値は2になります(0は成功を意味します。ゼロ以外の値は通常、異常が発生したか、エラーが発生したことを意味します)。

[root@Arch32-vm ~]# blkid /dev/sr0
[root@Arch32-vm ~]# echo $?
2
8
user606723

setcd -i(少なくともDebianではsetcdパッケージ内)がドライブの状態を教えてくれます。他のいくつかのアプローチとは異なり(少なくともマウント、おそらくblkidも)、これはnotトレイを閉じるように試みます、それが可能なドライブでも。 (あなたがディスクを入れている間にそれがあなたに近づこうとすると、これは本当に迷惑です).

トレイを開いた状態で:

 $ setcd -i /dev/sr0
/dev/sr0:
 CDトレイが開いています

トレイを閉じた直後:

 $ setcd -i /dev/sr0
/dev/sr0:
ドライブの準備ができていません

準備ができたら:

 $ setcd -i /dev/sr0
/dev/sr0:
ドライブにディスクが見つかりました:データディスクタイプ1 
ボリューム名:"name"
パブリッシャー:MKISOFS ISO 9660/HFS FILESYSTEM BUILDER&CDRECORD CD-R/DVD CREATOR(C)1993 E.YOUNGDALE(C)1997 J.PEARSON/J.SCHILLING2005030913034700�2005030913034700�0000000000000000
データ準備:MKISOFS ISO 9660/HFS FILESYSTEM BUILDER&CDRECORD CD-R/DVD CREATOR(C)1993 E.YOUNGDALE(C)1997 J.PEARSON/J.SCHILLING 2005030913034700�2005030913034700�0000000000000000

閉じていますが、ディスクはありません:

 $ setcd -i /dev/sr0
/dev/sr0:
ディスクが挿入されていません

あなたはそれをかなり簡単にスクリプトすることができます:

while true; do
    cdinfo=$(setcd -i "$dev")
    case "$cdinfo" in
        *'Disc found'*)
            break;
            ;;
        *'not ready'*)
            echo '(waiting for drive to be ready)' >&2;
            sleep 3;
            ;;
        *'is open'*)
            echo '(drive is open)' >&2;
            sleep 5;
            ;;
        *)
            printf 'Confused by setcd -i, bailing out:\n%s\n' "$cdinfo" &2
            exit 1
    esac
done
4
derobert

Python3と標準ライブラリで次のことができます。

import fcntl
import os

CDROM_DRIVE = '/dev/sr0'

def detect_tray(CDROM_DRIVE):
    """detect_tray reads status of the CDROM_DRIVE.
    Statuses:
    1 = no disk in tray
    2 = tray open
    3 = reading tray
    4 = disk in tray
    """
    fd = os.open(CDROM_DRIVE, os.O_RDONLY | os.O_NONBLOCK)
    rv = fcntl.ioctl(fd, 0x5326)
    os.close(fd)
    print(rv)
3
Scott

Lsblkコマンドで試すことができます:

lsblk -fp

行/ dev/sr0のFSTYPEの下に何もない場合->メディアがcdromドライブにロードされていません。 FSTYPEの下に何かがある場合、おそらくiso9660->メディアがcdromドライブにロードされています。

別の、私は最も簡単な方法だと思います:

cat /dev/sr0 | head -1

出力が次の場合:

cat: /dev/sr0: No medium found

->メディアがロードされていません。

出力がこれ以外の場合:

cat: /dev/sr0: No medium found

->メディアがロードされます。

通知:私はこれをオーディオでも空のCDでも試しませんでしたが、結果は同じになると思います。

3
Damir

このシェルスクリプトアプローチの問題は、トレイが閉じて初期化しているため、mount、lsblk、blkidのいずれのシェルコマンドも待機/ブロック/一時停止して、cdromが「メディアが見つかりません」と報告しているかどうかを判断できないことです。それ自体がCDを読み取るため、またはデバイスにCDがないため、「メディアが見つかりません」が永久に報告されます。したがって、以下のシェルスクリプトのように、あきらめる前に、特定のスリープ間隔でcdromデバイスを試そうとする妥当な回数の試行を選択するか、いくつかのioctl呼び出しでcコードを記述し、いくつかの情報を取得できます。カーネルを介して直接、CDROM。

#!/bin/sh

# cd.close
#
# Close the CD-ROM tray, and mount the CD-ROM device:
#
# mount status codes: see man mount(8)
# ------------------------------------
# 0   success
# 1   incorrect invocation or permissions
# 2   system error (out of memory, cannot fork, no more loop devices)
# 4   internal mount bug
# 8   user interrupt
# 16  problems writing or locking /etc/mtab
# 32  mount failure
# 64  some mount succeeded (in the case of mount -a)

CDROM=/dev/sr0
TRIES="1 2 3"
INTERVAL=5
MOUNT=0

TOKENS=( $TRIES )
STOP=${TOKENS[-1]}

for i in $TRIES; do
echo close: ATTEMPT $i of $STOP
output=`mount $CDROM -t iso9660 /cdrom 2>&1`
status=$?
echo mount: OUTPUT $output
echo mount: STATUS $status
if [ $status -eq 0 ]; then
  MOUNT=1
  break
else
  if [[ "$output" =~ "already mounted" ]]; then
    MOUNT=1
    break
  fi
fi
if [ $i -eq $STOP ]; then
  break
fi
echo sleep: $INTERVAL SECONDS...
sleep $INTERVAL
done

if [ $MOUNT -eq 1 ]; then
  echo final: MOUNTED $CDROM
  printf "final: LABEL "
  volname $CDROM
else
  echo final: NO MEDIUM
fi
1
Allan

デバイスをマウントしてみてください。

mount -t iso9660 /dev/sr0 /mnt/cdrom

次に、戻り値$?を確認します。

戻りが0、「良好」の場合、ディスクが存在していました。そうでなければ、それは、良くない「1」または「0」以外の何かを返します。

だから、黙ってチェックするために、私はそれをそのようにスクリプト化します。

cdrom_mount=0
mount -t iso9660 /dev/sr0 /mnt/cdrom >/dev/null 2>&1
if [[ $? -gt 0 ]]
    then
    cdrom_mount=true
else
    cdrom_mount=false
fi

これは非常に単純な例ですが、同様のことを行うことができます...

1
vparsons0u812

これが私が自分の目的で使用するシェルスクリプトです。 Allan の答えに部分的に基づいています。

その背後にある理由は、基本的には&&を使用して拡張シェルコマンドで使用していて、デバイスがマウントする準備ができるまで待機する必要があったためです。

#!/bin/bash
# mountdvd:
#   A Shell script to wait until the optical drive can be mounted.
#
#   Important Notes:
#    - By default, this will wait about 10 seconds for the drive to finish reading a newly
#      inserted disk.
#    - Works best already be given a mount point in /etc/fstab
#    - Works best if fs type is set to auto
#    - Assumes /etc/fstab allows user to mount device
#
#   Example /etc/fstab listing:
#    /dev/cdrom /media/dvd auto nofail,auto,user,exec,utf8,noatime,ro,uid=plex,gid=pi 0 0

# Command name
COMMAND=`basename $0`

# Device to mount
DVD_DEVICE=/dev/cdrom
MOUNT_POINT=/media/dvd

# Number of attempts before giving up (Total time = ATTEMPTS * WAIT_TIME, default: 10 seconds)
ATTEMPTS=20

# Wait time in seconds
WAIT_TIME=0.5

# Check if already mounted first
MOUTPUT=`mountpoint -q $MOUNT_POINT`
MSTATUS=$?

if [ $MSTATUS -eq 0 ]; then
    echo "$COMMAND: $DVD_DEVICE was already mounted."
    exit 0
fi

#for ATTEMPT in {1..$ATTEMPTS}
while [ $ATTEMPTS -gt 0 ];
do
    # Attempt to mount device
    OUTPUT=`mount $DVD_DEVICE 2>&1`
    STATUS=$?

    if [ $STATUS -eq 0 ]; then
        # Device mounted
        exit 0
    else
        # Double check here, just in case earlier check failed.
        if [[ "$OUTPUT" =~ "already mounted" ]]; then
            # Device was already mounted
            echo "$COMMAND: $DVD_DEVICE was already mounted."
            exit 0
        fi
    fi

    if [ $ATTEMPTS -ne 1 ]; then
        # Wait a moment before trying again.
        sleep $WAIT_TIME
    fi

    let ATTEMPTS=ATTEMPTS-1
done

echo "$COMMAND: ERROR: Unable to mount $DVD_DEVICE."
exit 1
0
Jason