이름에 변수 공백이 있는 USB를 자동으로 감지하고 쓰는 방법

이름에 변수 공백이 있는 USB를 자동으로 감지하고 쓰는 방법

두 번째 BASH 운동을 하고 있어요TLDP Bash 스크립팅 가이드, 연결된 USB 부분에 zip 파일을 복사하기 전까지 대부분의 내용을 파악했습니다.

홈 디렉토리 목록

사용자 홈 디렉터리의 재귀적 디렉터리 목록을 수행하고 해당 정보를 파일에 저장합니다. 파일을 압축하고 스크립트에서 사용자에게 USB 플래시 드라이브를 삽입하고 Enter 키를 누르라는 메시지를 표시하도록 합니다. 마지막으로 df 출력을 구문 분석하여 플래시 드라이브가 올바르게 마운트되었는지 확인한 후 파일을 플래시 드라이브에 저장합니다. 플래시 드라이브를 제거하기 전에 먼저 마운트 해제해야 합니다.

스크립트를 작성하면서 점점 우아함이 줄어들었고 이를 수행하는 더 좋은 방법이 있는지 궁금했습니다. 파일을 생성하는 것이 비교를 수행하는 가장 효율적인 방법이 아닐 수도 있다는 것을 알고 있지만 아직 셸 확장을 파악하지 못했고 일단 작동하면 변경할 계획입니다.

구체적인 질문은 USB가 마운트되어 있고 다른 곳이 아닌 USB에 쓰고 있는지 확인하는 것입니다. dfUSB를 연결한 후의 마지막 라인을 USB를 연결하기 전과 USB를 연결한 후의 마지막 라인을 비교하고 일치할 때까지 반복 합니다 df. 아쉽게도 결과는 >로 시작하는데, sed를 사용해서 없애도록 하겠습니다. 실제 문제는 내 USB 설치 경로가 다음과 같다는 것입니다.diffdfdfdiff

/media/flerb/"공백이 있는 USB 제목"

이 휴대용 USB의 이름을 다르게 만들려면 awk 및 필드 구분 기호를 사용하여 작업을 수행하는 것이 가장 좋습니다. 후속 조치로서 나는 이것이 매우 우아하지 않다는 것을 알고 있으며 이 문제를 해결할 수 있는 더 깔끔한 방법이 있는지 알고 싶습니다...특히 이것은 두 번째 연습이고 여전히 간단하기 때문입니다.

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 파일 시스템에 마운트되고 두 번째 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 $?

관련 정보