简体   繁体   中英

“read: -i: invalid option” in shell on OSX

This script was written for linux and I'm trying to adapt it for osx or use it as is:

#!/bin/bash
read -e -p "Serial Port                          :" -i "/dev/ttyUSB0" comport
read -e -p "Flash Size (example 512, 1024, 4096) :" -i "4096" fsize
read -e -p "Build (example 71, 72, ..)           :" -i "120" build

size="${fsize}K"
if [ $fsize -gt 1000 ]; then
    size=$(($fsize/1024))"M"
fi

echo "Expected Flash Size: $size"
echo "Using com port: $comport"
if [ -f ESPEasy_R${build}_${fsize}.bin ]; then
    echo "Using bin file: ESPEasy_R${build}_${fsize}.bin [FOUND]"
    ./esptool -vv -cd nodemcu -cb 115200 -bz $size -cp $comport -ca 0x00000 -cf ESPEasy_R${build}_${fsize}.bin
else
    echo "Expected bin file: ESPEasy_R${build}_${fsize}.bin [NOT FOUND!!!]"
fi

I'm trying to run it by going in to it's folder and writing ./flash.sh, but I get this error:

./flash.sh: line 2: read: -i: invalid option
read: usage: read [-ers] [-u fd] [-t timeout] [-p prompt] [-a array] [-n nchars] [-d delim] [name ...]
./flash.sh: line 3: read: -i: invalid option
read: usage: read [-ers] [-u fd] [-t timeout] [-p prompt] [-a array] [-n nchars] [-d delim] [name ...]
./flash.sh: line 4: read: -i: invalid option
read: usage: read [-ers] [-u fd] [-t timeout] [-p prompt] [-a array] [-n nchars] [-d delim] [name ...]
./flash.sh: line 7: [: -gt: unary operator expected
Expected Flash Size: K
Using com port: 
Expected bin file: ESPEasy_R_.bin [NOT FOUND!!!]

I believe I need to supply the options somehow, but I can't figure it out, they all seam to have the flag i and I also tried:

./flash.sh /dev/ttyUSB0 4096 120

As the error states, the version of bash shipped on MacOS doesn't support read -i .

You have some options:

  • Install a newer bash release. (3.2 is literally a decade out of date, since Apple refuses to be bound by the license used for 4.0 or newer; either MacPorts or Homebrew will make installing a new release easy, and using #!/usr/bin/env bash as the shebang in your script will ensure that the first version present in the PATH is used).
  • Rewrite your code to not need any functionality that isn't available.

As an example of the latter:

read -e -p "Serial Port (default: /dev/ttyUSB0)    :" comport; : "${comport:=/dev/ttyUSB0}"
read -e -p "Flash Size (default: 4096)             :" fsize;   : "${fsize:=4096}"
read -e -p "Build (default: 120)                   :" build;   : "${build:=120}"

You also mentioned the possibility of passing arguments on the command line. Frankly, it's generally good practice to allow that, and the folks who originally wrote your script should have done it. Using a function, below, to honor command-line values if given, prompt if not, and fall back to a default when appropriate:

#!/usr/bin/env bash

setvar() {
  local varname argument default prompt
  varname=$1; argument=$2; default=$3; prompt=$4
  if [[ $argument ]]; then
    printf -v "$varname" %s "$argument"
  elif read -r -e -p "$prompt" "$varname" && [[ $varname ]]; then
    return 0
  else
    printf -v "$varname" %s "$default"
  fi
}

setvar comport "$1" "Serial Port (default: /dev/ttyUSB0)    :" /dev/ttyUSB0
setvar fsize   "$2" "Flash Size (default: 4096)             :" 4096
setvar build   "$3" "Build (default: 120)                   :" 120

# ...etc here.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM