0

I have the following validation methods to read value of INSERT_AT from the user. INSERT_AT is supposed to be within a range of integers (0 < INSERT_AT < BOOKLENGTH) where $BOOKLENGTH can be provided by another method getLength().

Like so:

readValidInsertAt() {
  INSERT_AT=$1

  while ! { isValidArgument "$INSERT_AT" && isArgumentNumeric "$INSERT_AT" && isArgumentInRange "$INSERT_AT"; }; do
    echo -e 'Insert at?: \c'
    read -r INSERT_AT
  done
}

isArgumentInRange() {
  ARGUMENT=$1  

  # Smelly code here :(

  cd manuscript || exit;
  getLength
  cd ..

  if [[ "$ARGUMENT" -le "$BOOKLENGTH" ]] && [[ "$ARGUMENT" -ge 0 ]] ; then
    return 0
  else
    return 1
  fi

}

The thing is that I have CD into a directory before executing getLength() and then CD .. back again to get the $BOOKLENGTH. I'd want to avoid that using a subshell (...) perhaps.

getLength() {
  BOOKLENGTH=1
  until [ ! -d "page-$((BOOKLENGTH+1))"  ]; do
    BOOKLENGTH=$((BOOKLENGTH+1))
  done
}

length() {
  if [ -d manuscript/ ] ; then
    (cd manuscript || exit; getLength; echo "Book length is: ${BOOKLENGTH} pages.")
  else 
    echo "Manuscript not found, probably not in project root!"
  fi
}

Is there a way or a good pattern to do this? My code works but I'm unhappy with it.

1 Answer 1

1

Variables set in a subshell won't ever be seen in the parent shell. You could have the subshell echo the variable, and then assign that to a variable in the parent:

BOOKLENGTH=$(cd manuscript || exit; getLength; echo $BOOKLENGTH)
echo "Book length is: $BOOKLENGTH pages."

Not the answer you're looking for? Browse other questions tagged or ask your own question.