如何自动检测并写入名称中带有变量空格的USB

如何自动检测并写入名称中带有变量空格的USB

我正在做第二个 BASH 练习TLDP Bash 脚本指南,直到将压缩文件复制到插入的 USB 部分之前,我已经弄清楚了大部分内容。

主目录列表

对用户的主目录执行递归目录列表并将信息保存到文件中。压缩文件,让脚本提示用户插入 USB 闪存驱动器,然后按 ENTER。最后,通过解析 df 的输出确定闪存驱动器已正确安装后,将文件保存到闪存驱动器。请注意,在移除闪存驱动器之前必须先将其卸载。

随着我编写脚本的进展,它变得越来越不优雅,并且想知道是否有更好的方法来做到这一点。我知道创建文件可能不是进行比较的最有效方法,但尚未计算出 shell 扩展,并打算在其工作后对其进行更改。

具体问题是,确保 USB 已安装并且我正在写入 USB 而不是其他地方。我df将 USB 插入后的最后一行与USB 插入之前和USB插入后之间的最后一行进行比较,并循环直到它们df匹配。不幸的是,结果以 > 开头,但我打算使用 sed 来摆脱它。真正的问题是我的USB安装路径是:diffdfdfdiff

/media/flerb/"带有空格的 USB 标题"

为了使这个可移植的 USB 可能有不同的名称,我最好的选择是用 awk 和字段分隔符做一些事情?作为后续,我知道这非常不优雅,并且想知道是否有更干净的方法来解决这个问题......特别是因为这是第二个练习并且仍然是简单的。

df tails 的输出是:

/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 文件系统上,第二个 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=usb为 true 则安装在“/dev/sdb”上的设备是 USB 设备

  • 找到路径,并确保我抓住了正确的路径:df --output=source,avail,target | grep "$FILESYSTEM" | grep "$MOUNTPOINT"并且一些非常好的 awk

    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过滤的输出并对文件系统和挂载点进行 grep时获取错误的设备,那么至少它会失败。

试过了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 $?

相关内容