Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash 'read' command does not accept -i parameter on Mac. Any alternatives?

Tags:

bash

macos

I have a bash script that works fine on my work Ubuntu machine, but sadly breaks when I try and run it on my Mac OSX Lion Mountain Lion laptop. The line that kills it is this:

while [[ -z "$SSHFS_PATH" ]] ; do
  read -e -p "Please enter the path on which to mount your file system: `echo -e $'\n > '`" -i "~/aws-dev" SSHFS_PATH;
done

It throws out this error:

-bash: read: -i: invalid option
read: usage: read [-ers] [-u fd] [-t timeout] [-p prompt] [-a array] [-n nchars] [-d delim] [name ...]

So it seems the OSX version of the read command doesn't accept -i, which is used to suggest default values. Why? And what can be done to fix this?

Thanks :)

like image 351
Matt Fletcher Avatar asked Mar 25 '14 12:03

Matt Fletcher


2 Answers

One could write a wrapper function that detects whether -i is supported and use the appropriate syntax:

function readinput() {
  local CLEAN_ARGS=""
  while [[ $# -gt 0 ]]; do
    local i="$1"
    case "$i" in
      "-i")
        if read -i "default" 2>/dev/null <<< "test"; then 
          CLEAN_ARGS="$CLEAN_ARGS -i \"$2\""
        fi
        shift
        shift
        ;;
      "-p")
        CLEAN_ARGS="$CLEAN_ARGS -p \"$2\""
        shift
        shift
        ;;
      *)
        CLEAN_ARGS="$CLEAN_ARGS $1"
        shift
        ;;
    esac
  done
  eval read $CLEAN_ARGS
}

and then

readinput -e -p "This is a test of... " -i "default value" variable
variable=${variable:-default value}

Note: if you call this function read, it will then replace the not-so-functional builtin.

like image 153
Maxim Belkin Avatar answered Sep 19 '22 16:09

Maxim Belkin


Mac OS X 10.7 Lion (and to this date all more recent versions as well, thanks @kojiro) ships with bash 3.2 whereas read -i was introduced with bash 4.0-alpha (see the ChangeLog).

You can either install a more recent version of bash using homebrew or provide a non-readline default value yourself, e.g.

read -p "Path? (default: /bar): " var
[ -z "${var}" ] && var='/bar'
like image 21
Adrian Frühwirth Avatar answered Sep 21 '22 16:09

Adrian Frühwirth