web-dev-qa-db-ja.com

USBフラッシュメモリスティックへのパスを出力するBashスクリプト

Bash(UbuntuおよびLinux Mint)を使用してローカルコンピューターに接続されているUSBフラッシュメモリスティックへのパスを返す(出力する)にはどうすればよいですか?

バックグラウンド:

ユーザーに自動バックアップスクリプトを提供しています。 (実際のバックアップソフトウェアは既にコンピューターにインストールされています。)

ユーザーの仕事は、USBフラッシュメモリスティックを接続し、端末で1つのコマンドを入力することです(パラメータ、オプション、またはその他の変数情報はありません)。

USBフラッシュメモリスティックへのパスを見つけることができるbashスクリプトが必要です。そのようなパスが複数見つかった場合は、おそらく中止して、メッセージが表示されて私に連絡します。複雑なスクリプトを作成するよりも、バックアップを実行するときに1つのメモリースティックだけがコンピューターに接続されていることを確認するように指示する方が簡単です。

3
MountainX

USBデバイスを接続すると、次のパスを確認するだけで、何がインストールされたかがわかります。

$ ls -l /dev/disk/by-id/usb*

$ ls -l /dev/disk/by-id/usb*
lrwxrwxrwx. 1 root root  9 Mar 12 01:01 /dev/disk/by-id/usb-JMTek_USBDrive-0:0 -> ../../sdb
lrwxrwxrwx. 1 root root 10 Mar 12 01:01 /dev/disk/by-id/usb-JMTek_USBDrive-0:0-part1 -> ../../sdb1

上記の情報を使用すると、スクリプトはreadlinkのようなものを使用してこれらのエントリを簡単に確認できます。

$ readlink -f /dev/disk/by-id/usb-JMTek_USBDrive-0:0*
/dev/sdb
/dev/sdb1

次に、mountコマンドを使用して、デバイスが自動マウントされたディレクトリを確認します。

$ mount | grep '/dev/sdb\b'
$ mount | grep '/dev/sdb1\b'
/dev/sdb1 on /run/media/saml/HOLA type vfat (rw,nosuid,nodev,relatime,uid=1000,gid=1000,fmask=0022,dmask=0077,codepage=437,iocharset=ascii,shortname=mixed,showexec,utf8,flush,errors=remount-ro,uhelper=udisks2)

これは、次のように1つのライナーに拡張できます。

$ readlink -f /dev/disk/by-id/usb-JMTek_USBDrive-0:0* | \
    while read dev;do mount | grep "$dev\b" | awk '{print $3}';done
/run/media/saml/HOLA

デバイスのIDを取得する

これは、/dev/disk/by-id/usb*の出力から次のように解析できます。

$ ls /dev/disk/by-id/usb* | sed 's/.*usb-\(.*\)-[0-9]:.*/\1/'
JMTek_USBDrive
JMTek_USBDrive

ちなみに、この情報は、USBの製造元と製品の説明を連結したものです。

$ usb-devices
...
T:  Bus=02 Lev=02 Prnt=02 Port=01 Cnt=02 Dev#= 10 Spd=12  MxCh= 0
D:  Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
P:  Vendor=058f ProdID=9380 Rev=01.00
S:  Manufacturer=JMTek
S:  Product=USBDrive
C:  #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=100mA
I:  If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage
...

USBデバイスが使用しているデバイス(/dev/sd*)を確立したら、UDEVから次のようにアクセスすることもできます。

$ udevadm info --query=all --name=sdb | grep -E "MODEL=|VENDOR=|ID_SERIAL"
E: ID_MODEL=USBDrive
E: ID_SERIAL=JMTek_USBDrive-0:0
E: ID_VENDOR=JMTek
5
slm

/ etc/mtabを調べてマウントされたデバイスを確認するスクリプトを記述し、udevadmを使用してそれらがUSBデバイスであるかどうかを確認できます。/etc/mtabには、/ dev内のデバイスの名前とそのマウントポイントの両方が含まれます。だからあなたは次のようなことをすることができます:

IFS=$'\n'
for mtabline in `cat /etc/mtab`; do 
  device=`echo $mtabline | cut -f 1 -d ' '`
  udevline=`udevadm info -q path -n $device 2>&1 |grep usb` 
  if [ $? == 0 ] ; then
    devpath=`echo $mtabline | cut -f 2 -d ' '`
    echo "devpath: $devpath"
  fi
done

(スクリプトでIFSを設定して、mtabが「Word」ごとではなく1行ずつ読み取られるようにする必要があります)。

2
rainbowgoblin

USBフラッシュデバイスが存在しないデスクトップの場合:

% lsblk -o tran,name,mountpoint
> TRAN   NAME   MOUNTPOINT
> sata   sda
>        ├─sda1 /esp
>        ├─sda2 /
>        ├─sda3 /mnt/sda3
>        ├─sda4
>        └─sda5
> sata   sdb
> sata   sdc
> sata   sr0

2つの私のラップトップで:

% lsblk -o tran,name,mountpoint
> TRAN   NAME   MOUNTPOINT
> usb    sda
>        ├─sda1 /esp
>        └─sda2 /
> usb    sdb
>        └─sdb1 /home
> sata   sr0

必要なのはそれだけです。

そのため、一部のDebianファミリシステムはまだトランスポートオプションをサポートしていないと言う人もいます。その場合、これを試してください:

    ( set -- $(lsblk -ndo name,rm)
        while [ $# -ge 2 ] ; do {
            [ $2 -eq 1 ] && \
                udevadm info --query=all --name "/dev/$1"
        shift 2 
     } ; done )   

上記のコマンドは、最初にlsblkに、現在の(親のみ-したがってsdaのみでsda1ではない)ブロックデバイスのリストを名前とremovableフラグの列で照会します。出力は次のようになります。

sda 0
sdb 1
sdc 1

1のフラグが付いたデバイスのみが取り外し可能です。

したがって、set _(サブシェルの)位置パラメータを分割コンテンツに追加し、エントリごとに2つのパラメータを作成します。 while[リムーバブルフラグ] $2に対して少なくとも2つの位置パラメータwe1 test &&があり、存在する場合は、システムのデバイスマネージャにudevadmにクエリを実行してすべての情報を取得します最初の位置パラメータ、または/dev/$1。次のshift最初の2位置パラメータを離れて、次の2つからやり直します。

udevadmは、興味があるかもしれないデバイスに関する多くの情報を提供しますが、本当に要点を知りたい場合は、次の|pipeudevadmstdoutに追加できます。

    udevadm info --name "/dev/$1" |\
        grep -q ID_BUS=usb && echo "/dev/$1"

これだけで、現在システムに存在する親/ dev/$ DEVリムーバブルUSBブロックデバイスのみのリストが次の形式で提供されます。

/dev/$DEV /dev/$ALSODEV

この時点で、上記で提供された親リンクのマウントされたパーティションのマウントポイントのみに関心がある場合は、次のようにfindmntと一緒にすべてをロールできます。

( set -- $(lsblk -ndo name,rm)
    while [ $# -ge 2 ] ; do {
        [ $2 -eq 1 ] &&
            udevadm info --query=all --name "/dev/$1" |\
            grep -q ID_BUS=usb &&
                 printf 'findmnt %s -no TARGET ;' "/dev/$1" /dev/"$1"[0-9]
        shift 2 ; } ; done ) |\ 
    . /dev/stdin

これにより、次のようなリストが提供されます。

/removable/usb/device/mount/point/1
/ditto/2
/also/3
0
mikeserv