0

I need help with the shell script I'm trying to execute as follow;

#!/bin/bash

other_oufdir () {
  if [[ $(echo "$oufdir"|awk -F"/" '{print $2"/"$3}') != data[1-2]/store ]];then
    echo " is not allowed!" && force_oufdir
  fi
}

force_oufdir () {
  read -r -p "Force output dir? : "
  if [[ ! $REPLY =~ ^[Yy]$ ]]
  then
    :
  else
    exit 1
  fi
}

read -r -p "Enter output dir? : " oufdir
if [[ -z "$oufdir" ]]
then
  echo "Cannot be empty!" && echo && exit 1
fi
other_oufdir
if [[ ! -d "$oufdir" ]]
then
  mkdir -p -- "$oufdir" && cd "$oufdir"
else
  cd "$oufdir" || return
fi

Output is ...

Enter output dir? : /data1/backup/A1
 is not allowed!
FORCE output dir? : y

What I want the echo message should be on the same line. Is this possible?

Enter output dir? : /data1/backup/A1 is not allowed!
FORCE output dir? : y
emilee
  • 25
  • 7
  • `echo -n` or use `printf`? – Jetchisel Jul 20 '20 at 02:03
  • 2
    Better `printf`, as `echo -n` behavior is undefined by POSIX and can vary between shells, and even between runtime configurations (active environment variable contents &c) when the shell is known to be bash. More at [Why is printf better than echo?](https://unix.stackexchange.com/questions/65803/why-is-printf-better-than-echo) on [unix.se]. – Charles Duffy Jul 20 '20 at 02:04
  • The question is about showing the message after what the user has written on an input prompt. `printf` and `echo -n` won't do that. – that other guy Jul 20 '20 at 02:07
  • @CharlesDuffy : I think `echo -n` would be safe here, because the OP explicitly asks for a _bash_ solution and does say that he needs Posix compatibility. BTW, the same applies to `printf`, which is an internal bash command, just as `echo` is. – user1934428 Jul 20 '20 at 09:09
  • 1
    @user1934428, `printf` is POSIX-specified; *all* standard-compliant shells provide a consistent implementation (there may be extensions like `%q`, but all the standard-compliant bits are guaranteed to behave the same way). `echo`'s specification is much more wibbly-wobbly, and doing anything with `-n` other than printing it is strictly optional behavior. In bash, try running `set -o posix; shopt -s xpg_echo; echo -n "something"` -- you'll see it write `-n something` to output, as demonstrated at https://ideone.com/2YoDL2. – Charles Duffy Jul 20 '20 at 10:21
  • 2
    @user1934428, ...and the thing is, you don't even need to run `set -o posix; shopt -s xpg_echo` in your script for those options to be in effect in bash; they can be set as defaults at compile-time, or turned on through environment variables inherited from a parent process. – Charles Duffy Jul 20 '20 at 10:23

1 Answers1

2

We take for granted the fact that /data1/backup/A1 shows up on the screen when the user types it, but someone had to implement that. Showing characters being typed is known as "local echo".

The logical extension of this is that the line breaks after input: the user also presses enter, so the terminal also shows the enter key.

Almost all other programs work this way, so it's well known and canonical behavior. You should consider making your own life easier by just working with the system, rather than fighting it to get some exact behavior you want.

If you still really want to do it, you can:

  1. Disable local echo
  2. Read character by character
  3. Handle line editing characters, like backspace
  4. Break when the user presses enter, and avoid showing it
  5. Show any other character on screen
  6. Once done, print your message

Here's an example:

#!/bin/bash
  
str=""
echo -n "Enter output dir? : "
while IFS= read -rs -d "" -n 1 c
do
  case "$c" in
    $'\n') break ;;                # Enter: Don't show it, just stop
    $'\177'|$'\b') str=${str%?} ;; # Backspace: Remove last character
    *) str+="$c"                   # Otherwise print and append
       printf '%s' "$c" ;;
  esac
done

echo " is not allowed."

When you input something and hit enter, the "is not allowed" message shows on the same line.

that other guy
  • 116,971
  • 11
  • 170
  • 194