0

I'm using Red Hat - based Linux. I'm using this bash script to find all USB devices and place it to selectList:

read -a devices <<< $(ls -l --time-style=long-iso /dev/disk/by-id)

while [[ ${devices[i]} != "" ]]
do
  if [[ ${devices[i]} == usb-* ]] ; 
  then
    if [[ ! ${devices[i+2]} =~ [0-9]$ ]] ; 
    then
      selectList+=${devices[i]}" "
    fi
  fi
  let "i++"
done

For old Linux distributives (old Fedora, CentOS 7) it works OK. But on Fedora 32 this string don't work:

read -a devices <<< $(ls -l --time-style=long-iso /dev/disk/by-id)

because

<<< $(ls -l --time-style=long-iso /dev/disk/by-id)

returns only first string of result ls command.

For example, command

tail -n1 <<< $(ls -l --time-style=long-iso /dev/disk/by-id)

returns on CentOS 7

total 0 lrwxrwxrwx 1 root root 9 2020-07-14 10:23 ata-Optiarc_DVD_RW_AD-5280S -> ../../sr0 lrwxrwxrwx 1 root root 9 2020-07-14 10:23 ata-ST3500514NS_9WJ16TBB -> ../../sda lrwxrwxrwx 1 root root 9 2020-07-14 10:23 ata-ST500DM002-1BD142_Z3T5RLF8 -> ../../sdb lrwxrwxrwx 1 root root 11 2020-07-14 10:23 md-uuid-6a3d48a2:fbd5af07:9ce92935:f469dfc7 -> ../../md127 lrwxrwxrwx 1 root root 11 2020-07-14 10:23 md-uuid-721d0cf4:5fc67883:dbbd7d4c:47ff4941 -> ../../md126 lrwxrwxrwx 1 root root 13 2020-07-14 10:23 md-uuid-721d0cf4:5fc67883:dbbd7d4c:47ff4941-part1 -> ../../md126p1 lrwxrwxrwx 1 root root 13 2020-07-14 10:23 md-uuid-721d0cf4:5fc67883:dbbd7d4c:47ff4941-part2 -> ../../md126p2 lrwxrwxrwx 1 root root 13 2020-07-14 10:23 md-uuid-721d0cf4:5fc67883:dbbd7d4c:47ff4941-part3 -> ../../md126p3 lrwxrwxrwx 1 root root 13 2020-07-14 10:23 md-uuid-721d0cf4:5fc67883:dbbd7d4c:47ff4941-part4 -> ../../md126p4 lrwxrwxrwx 1 root root 13 2020-07-14 10:23 md-uuid-721d0cf4:5fc67883:dbbd7d4c:47ff4941-part5 -> ../../md126p5 lrwxrwxrwx 1 root root 9 2020-07-14 10:23 wwn-0x5000c5002e22dc64 -> ../../sda lrwxrwxrwx 1 root root 9 2020-07-14 10:23 wwn-0x5000c5004e81f353 -> ../../sdb

but on Fedora 32 it returns

lrwxrwxrwx 1 root root 9 2020-07-14 10:23 wwn-0x5000c5004e81f353 -> ../../sdb
Ivan
  • 21
  • 3
  • Probably different shells and/or different versions of same. Better program in POSIX-style. May I bring to your attention: https://stackoverflow.com/questions/5725296/difference-between-sh-and-bash –  Jul 15 '20 at 13:46
  • 3
    Do not attempt to parse `ls` output. Read [Why you shouldn't parse the output of ls](https://mywiki.wooledge.org/ParsingLs) – M. Nejat Aydin Jul 15 '20 at 13:48
  • 1
    Do you need the timestamp and symlink info? Seems like a plain `for device in /dev/disk/by-id/*; do-stuff $device; done` would work for you. – micke Jul 15 '20 at 14:34
  • Why would you want to do this with an array? It seems much cleaner to let each device be output on a separate line and do `while read device; do ...` Saves you the trouble of keeping track of an index and is a lot easier to understand. – William Pursell Jul 15 '20 at 16:12
  • what happens when quote *here* string with double quotes? `<<< "$(...)"` – alecxs Jul 15 '20 at 17:56

1 Answers1

0

The problem is resolved. This script allows the user to select USB Flash and put path to the device into a $deviceName variable.

for device in /dev/disk/by-id/*; 
do 
  if [[ $device == /dev/disk/by-id/usb-* ]] ;
  then
    device1=${device/"/dev/disk/by-id/"/}
    
    read -a devices <<< $(ls -l --time-style=long-iso /dev/disk/by-id | grep $device1)

    if [[ ! ${devices[9]} =~ [0-9]$ ]] ; 
    then
      selectList+=${devices[7]}"->/dev/"${devices[9]##*/}" "
    fi
  fi
done

if [ "$selectList" = "" ] ; then
    echo -e "ERROR: No USB devices found\n\r"
    exit 1
fi

echo "select the USB device"

select usbName in $selectList
do
  if [[ $usbName != "" ]] ;
  then
    break
  else
    echo "wrong USB device number"
  fi
done

deviceName="/dev/"${usbName##*->/dev/}
Ivan
  • 21
  • 3