0

Ok, this is going to seem like a basic question at first, but please hear me out. It's more complex than the title makes it seem!

Here is the goal of what I am trying to do. I would like to output to console similar to Linux boot.

Operating system is doing something...                                                 [ OK ]

Now this would seem to be obvious... Just use printf and set columns. Here is the first problem. The console needs to first print the action

Operating system is doing something...

Then it needs to actually do the work and then continue by outputting to the same line with the [ OK ].

This would again seem easy to do using printf. Simply do the work (in this case, call a function) and return a conditional check and then finish running the printf to output either [ OK ] or [ FAIL ]. This technically works, but I ran into LOTS of complications doing this. This is because the function must be called inside a subshell and I cant pass certain variables that I need. So printf is out.

How about just using echo -n? That should work right? Echo the first part, run the function, then continue echoing based on the return to the same line. The problem with this solution is I can no longer preserve the column formatting that I can with printf.

Operating system is doing something...                                             [ OK ]
Operating system is doing something else...                                             [ OK ]
Short example...                                             [ OK ]

Any suggestions how I can fix any of these problems to get a working solution? Thanks

Here is another way I tried with printf. This gives the illusion of working, but the method is actually flawed because it does not give you the progress indication, ie the function runs first before it ever prints out the the function is running. The "hey im doing stuff" prints immediately with the "hey im done" message. As a result, its pointless.

VALIDATE $HOST; printf "%-50s %10s\n" " Validating and sanitizing input..." "$(if [ -z "$ERROR" ]; then echo "[$GREEN   OK   $RESET]"; else echo "[$RED  FAIL  $RESET] - $ERROR"; echo; exit; fi)"
Atomiklan
  • 5,164
  • 11
  • 40
  • 62
  • "the function must be called inside a subshell and I cant pass certain variables that I need. So printf is out...?" You can't export the variables so they are available in the child's environment? Otherwise, just use `tput` and output the `[ OK ]` or `[ FAIL ]` at the right margin of the terminal. (see: `man 5 terminfo` and `man 1 tput`. See [print to the end of terminal](https://stackoverflow.com/questions/35052500/print-to-the-end-of-terminal) – David C. Rankin Feb 25 '19 at 07:05
  • Yes I looked into passing the variables, but apparently it is not possible to pass the variables from the sub shell. Using tput would be a solution, although not ideal. I know I said I wanted it to be like Linux boot, but I should clarify. I was just using that for descriptive purposes. Ideally the [ OK ] will not be too far over. Any other potential solutions? – Atomiklan Feb 25 '19 at 07:09
  • You can always output it at a fixed location from the right side (e.g. like 'right - 40') whatever you like. You can also use ANSI escapes, but `tput` is preferrable as it eliminates some of the terminal dependencies. – David C. Rankin Feb 25 '19 at 07:14

1 Answers1

1

There's no particular reason all the printf strings have to be printed together, unless you're worried some code you call is going to move the cursor.

Reordering your example:

printf "%-50s " " Validating and sanitizing input..."

VALIDATE $HOST

if [ -z "$ERROR" ]; then
    printf "%10s\n" "[$GREEN   OK   $RESET]";
else
    printf "%10s\n" "[$RED  FAIL  $RESET] - $ERROR"
    echo
    exit
fi

I have no idea what $ERROR contains or where it is supposed to display.

jhnc
  • 11,310
  • 1
  • 9
  • 26