私はNASで100個のCD / DVDを読むための迅速で簡単なスクリプトを書いています。トレイの取り出しとロードを処理しますが、メディアをトレイに挿入した後、OSがメディアを使用できなくなるのを待つか防止する簡単な方法が見つかりませんでした。
eject -t
トレイを閉じた直後に終了mount
失敗するだろうメディアが見つかりません直後に実行される場合は、eject
15秒後に実行されることもあります。
ディスクはかなり古く、一部は利用可能になるまでにかなり時間がかかりますので、「2分間スリープモード」ではない解決策は避けたいと思います。どんなアイデアがありますか? Ubuntu 18.04を使用してください。
答え1
大丈夫ですか?
while ! dd if=/dev/sr2 bs=2048 count=1 of=/dev/null 2>/dev/null; do sleep 1; done
/dev/sr2
実際のCD / DVDデバイスと交換してください。
No medium found
以下を除くエラーを確認して、より強力にすることができます。破損したDVDがないのでテストされませんでした。
dev=/dev/sr2
while :; do
err=$(dd if=$dev of=/dev/null bs=2048 status=none count=1 2>&1)
case $err in
"dd: failed to open '$dev': No medium found")
sleep 1 ;;
'')
# successfully opened
break ;;
*)
# unexpected error
# play some SOUND in the speakers
# and wait for user input to continue
read wtf ;;
esac
done
修正する:
これをサポートするドライブでは、Linuxはデバイスを開こうとすると自動的にトレイを閉じます。この機能は潜在的に無効になる可能性がありますが、ioctl(CDROM_CLEAR_OPTIONS, CDO_AUTO_CLOSE)
それを実装するコマンドラインユーティリティは見つかりません。なぜなら、人々はC
すべてをよりよく使うように強制するからですC
。
ここでは、CD / DVDドライブの状態を確認してポーリングできる小さなアプリケーションがあります。
単一引数で呼び出す場合:
cdstatus /dev/sr1
、または次のいずれかの状態が印刷されます/dev/sr1
。no_disc
tray_open
drive_not_ready
disc_ok
2つのパラメータを使用して呼び出す場合:
cdstatus /dev/sr1 1.3
/dev/sr1
状態になるまで1.3秒ごとにポーリングしますdisk_ok
。
cc -Os -Wall cdstatus.c -s -o cdstatus
gccおよびlibc6-devパッケージがインストールされている場合。
cdstatus.c
#include <sys/ioctl.h>
#include <linux/cdrom.h>
#include <fcntl.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <poll.h>
int main(int argc, char **argv){
int fd, s; int pt = -1;
if(argc < 2)
errx(1, "usage: %s /dev/srX [poll_secs] [verbose]", argv[0]);
if((fd = open(argv[1], O_RDONLY|O_NONBLOCK)) == -1)
err(1, "open %s", argv[1]);
if(argc > 2 && ((pt = strtod(argv[2], 0) * 1000) < 1 || pt > 3600000))
errx(1, "bad timeout '%s'", argv[2]);
redo:
switch(s = ioctl(fd, CDROM_DRIVE_STATUS, 0)){
case -1: err(1, "ioctl(CDROM_DRIVE_STATUS)");
case CDS_NO_INFO: errx(1, "ioctl(CDROM_DRIVE_STATUS) not implemented");
}
if(pt < 0 || argc > 3)
switch(s){
case CDS_NO_DISC: printf("no_disc\n"); break;
case CDS_TRAY_OPEN: printf("tray_open\n"); break;
case CDS_DRIVE_NOT_READY: printf("drive_not_ready\n"); break;
case CDS_DISC_OK: printf("disc_ok\n"); break;
default: printf("status=%d\n", s); break;
}
if(pt > 0 && s != CDS_DISC_OK){
if(poll(0, 0, pt) < 0) err(1, "poll");
goto redo;
}
return s != CDS_DISC_OK;
}
答え2
最後のものこのあいまいな関連スレッドに投稿してください。wodim -atip
とりわけ、Linuxの問題に推奨され、メディアが利用可能になるまでブロックするのに効果的であることが証明されています。
#!/bin/bash
set -e
DRIVE=${DRIVE:-"sr0"}
DESTROOT=${DESTROOT:-"/mnt/newshare"}
DRV_FULLNAME="$(</sys/class/block/$DRIVE/device/vendor) $(</sys/class/block/$DRIVE/device/model)"
[ -d /tmp/$DRIVE ] || mkdir /tmp/$DRIVE
while true; do
eject /dev/$DRIVE
echo "$DRV_FULLNAME is ready."
read -p "Enter next disc code: " DISC
if [ -z "$DISC" ]; then
echo "No disc code = we're done, exiting"
break
fi
eject -t /dev/$DRIVE || {
read -n1 -r -p "Unable to load tray. Push it in and hit Any key..."
echo
}
wodim dev=/dev/$DRIVE -atip > /dev/null || {
echo "Medium not detected."
break
}
mount /dev/$DRIVE /tmp/$DRIVE -o ro || {
echo "Couldn't mount medium."
break
}
cp -ia /tmp/$DRIVE/. $DESTROOT/$DISC/ || {
echo "COPY FAILED. Put it on the read-error pile and continue with next one."
}
done