名前に変数スペースがあるUSBを自動的に検出して書き込む方法

名前に変数スペースがあるUSBを自動的に検出して書き込む方法

2回目のBASH運動をしています。TLDP Bashスクリプトガイド、接続されたUSB部分にzipファイルをコピーするまで、ほとんどの内容を把握しました。

ホームディレクトリ一覧

ユーザーホームディレクトリの再帰的なディレクトリリストを実行し、その情報をファイルに保存します。ファイルを圧縮し、スクリプトからユーザーにUSBフラッシュドライブを挿入してEnterキーを押すように求めます。最後に、df出力を解析してフラッシュドライブが正しくマウントされていることを確認し、ファイルをフラッシュドライブに保存します。フラッシュドライブを取り外す前に、まずマウントを解除する必要があります。

スクリプトを書いている間、ますます優雅さが減り、これを行うより良い方法があるかどうか疑問に思いました。ファイルを生成することは比較を実行する最も効率的な方法ではないかもしれないことを知っていますが、まだシェル拡張を理解していないので、それがうまくいったら変更する予定です。

具体的な質問は、USBがマウントされていて、他の場所ではなくUSBに書き込んでいることを確認することです。dfUSBを接続した後の最後の行をUSBを接続する前とUSBを接続した後の最後の行を比較し、一致するまで繰り返しますdf。残念ながら結果は>で始まりますが、sedを使って取り除くようにします。実際の問題は、私のUSBインストールパスが次のようになることです。diffdfdfdiff

/media/flerb/「空白のあるUSBタイトル」

このポータブルUSBの名前を異なるようにするには、awkとフィールド区切り文字を使用して操作を実行するのが最善です。フォローアップとして、私はこれが非常にエレガントではないことを知っており、この問題を解決するためのよりきれいな方法があるかどうかを知りたいのですが...特にこれは2番目の練習であり、まだ簡単なためです。

dfテールの出力は次のとおりです。

/dev/sdb1                     15611904  8120352   7491552  53% /media/flerb/CENTOS 7 X8
> /dev/sdb1                     15611904  8120352   7491552  53% /media/flerb/CENTOS 7 X8

これまでのスクリプト

 1 #!/bin/bash
  2 
  3 if [ "$UID" -eq 0 ] ; then
  4         echo "Don't run this as root"
  5         exit 1
  6 fi
  7 
  8 #Create a backup file with the date as title in a backup directory
  9 BACKUP_DIR="$HOME/backup"
 10 DATE_OF_COPY=$(date --rfc-3339=date)
 11 BACKUP_FILE="$BACKUP_DIR/$DATE_OF_COPY"
 12 
 13 [ -d "$BACKUP_DIR" ] || mkdir -m 700 "$BACKUP_DIR"
 14 
 15 #find all files recursively in $HOME directory
 16 find -P $HOME >> "$BACKUP_FILE"
 17 
 18 #use lzma to compress
 19 xz -zk --format=auto --check=sha256 --threads=0 "$BACKUP_FILE"
 20 
 21 #making files to use in operations
 22 BEFORE="$BACKUP_DIR"/before_usb.txt
 23 AFTER="$BACKUP_DIR"/after_usb.txt
 24 DIFFERENCE="$BACKUP_DIR"/difference.txt
 25 
 26 df > "$BEFORE"
 27 read -p 'Enter USB and press any button' ok
 28 sleep 2
 29 df > "$AFTER"
 30 diff "$BEFORE" "$AFTER" > "$DIFFERENCE"
 31 sleep 2
 32 echo
 33 
 34 TAIL_AFTER=$(tail -n 1 "$AFTER")
 35 TAIL_DIFF=$(tail -n 1 "$DIFFERENCE")
 36 
 37 until [ "$TAIL_AFTER" == "$TAIL_DIFF" ] ;
 38 do
 39         echo "Not yet"
 40         df > "$AFTER"
 41         TAIL_AFTER=$(tail -n 1 "$AFTER")
 42         diff "$BEFORE" "$AFTER" > "$DIFFERENCE"
 43         TAIL_DIFF=$(tail -n 1 "$DIFFERENCE")
 44         echo "$TAIL_AFTER"
 45         echo "$TAIL_DIFF"
 46         sleep 1
 47 
 48 done
 49 exit $?

答え1

正しいUSBとそのパスを取得するには:

  • 私のシステムに接続されている最初のUSBは/ dev / sdb1ファイルシステムにマウントされ、2番目のUSBは/ dev / sdc1ファイルシステムにマウントされます。udevadm info -q all -n "/dev/sdb" | grep "ID_BUS=usb"trueが返されると、/ dev / sdc1に切り替えるセクションが追加されました。

  • diff前面と背面の間に「/media/darren」がある場合は、新しいUSBになる可能性があります。df --output=target | grep "/media/darren"USBがインストールされています。

  • if udevadm info -q all -n "/dev/sdb" | grep "ID_BUS=usbtrueの場合、「/dev/sdb」にインストールされているデバイスはUSBデバイスです。

  • パスを見つけて正しいパスを選択していることを確認してくださいdf --output=source,avail,target | grep "$FILESYSTEM" | grep "$MOUNTPOINT"本当に良いものがあります。

    udevadm info -q all -n "$FILESYSTEM" | grep "ID_BUS=usb" > $RESULT
    USB_ADDR="$BACKUP_DIR"/usb_addr.txt
    if grep "ID_BUS=usb" "$RESULT" ; then
        df --output=source,avail,target | grep "$FILESYSTEM" | grep "$MOUNTPOINT" > "$USB_ADDR"
        awk -i inplace '{$0=gensub(/\s*\S+/,"",1)}1' "$USB_ADDR"
        awk -i inplace '{$0=gensub(/\s*\S+/,"",1)}1' "$USB_ADDR"
        sed -i 's/^ *//' "$USB_ADDR"
    

残念ながら、他のものを追加または削除すると比較が失敗します。ただし、dfフィルタリングされた出力を使用してファイルシステムとマウントポイントをgrepingするときに誤ったデバイスを取得すると、少なくとも失敗します。

それを試みたawk 'NR!=1{print $NF}' <(df)|sort。 bash拡張はまだあまり良くありません。

#!/bin/bash

if [ "$UID" -eq 0 ] ; then
        echo "Don't run this as root"
        exit 50
fi

#Create a backup file with the date as title in a backup directory
BACKUP_DIR="$HOME/backup"
DATE_OF_COPY=$(date --rfc-3339=date)
BACKUP_FILE="$BACKUP_DIR/$DATE_OF_COPY"

[ -d "$BACKUP_DIR" ] || mkdir -m 700 "$BACKUP_DIR"

#find all files recursively in $HOME directory
find -P $HOME >> "$BACKUP_FILE"

#use lzma to compress
xz -zk --format=auto --check=sha256 --threads=0 "$BACKUP_FILE"

#making files to use in operations of before and after usb is inserted info and diff between them
#this is part of how we will insure that we are writing to the correct device
BEFORE="$BACKUP_DIR"/before_usb.txt
AFTER="$BACKUP_DIR"/after_usb.txt
DIFFERENCE="$BACKUP_DIR"/difference.txt
#MOUNTPOINT=where computer mounts USBs by default
MOUNTPOINT="/media/darren"
FILESYSTEM="/dev/sdb"
RESULT="$BACKUP_DIR"/result.txt


#if there is something on the mountpoint before we plug in the usb, we want to know
#so the new device is written to
udevadm info -q all -n "$FILESYSTEM" | grep "ID_BUS=usb" > $RESULT
if grep "ID_BUS=usb" "$RESULT" ; then
        FILESYSTEM="/dev/sdc"
        echo $FILESYSTEM
fi        

df --output=target | grep $MOUNTPOINT > "$BEFORE"

read -p 'Enter USB or hard drive and press any button' ok

df --output=target | grep $MOUNTPOINT > "$AFTER"
#dif them to find the new one
diff "$BEFORE" "$AFTER" > "$DIFFERENCE"

# Look in mountpoint in the difference between the before and after df outputs
SEARCH_FOR_MOUNT=$(grep "$MOUNTPOINT" "$DIFFERENCE")

until [ "$SEARCH_FOR_MOUNT" ] ;
do
        df --output=target | grep $MOUNTPOINT > "$AFTER"
        diff "$BEFORE" "$AFTER" > "$DIFFERENCE"
        SEARCH_FOR_MOUNT=$(grep "$MOUNTPOINT" "$DIFFERENCE")

done
#check if new device plugged into filesystem is a USB
udevadm info -q all -n "$FILESYSTEM" | grep "ID_BUS=usb" > $RESULT
USB_ADDR="$BACKUP_DIR"/usb_addr.txt
if grep "ID_BUS=usb" "$RESULT" ; then
        df --output=source,avail,target | grep "$FILESYSTEM" | grep "$MOUNTPOINT" > "$USB_ADDR"
        awk -i inplace '{$0=gensub(/\s*\S+/,"",1)}1' "$USB_ADDR"
        awk -i inplace '{$0=gensub(/\s*\S+/,"",1)}1' "$USB_ADDR"
        sed -i 's/^ *//' "$USB_ADDR"

        if [ ! -s $USB_ADDR ] ; then
              echo "Error finding USB Address"
              exit 100


        ADDR=$(cat "$USB_ADDR")
        cp "$BACKUP_FILE.xz" "$ADDR"
        rm "$BACKUP_FILE" "$USB_ADDR" "$RESULT" "$BEFORE" "$AFTER" "$DIFFERENCE"

else
        echo "Device is not a USB"
        exit 52
fi

exit $?

関連情報