mbland / go-script-bash

Framework for writing modular, discoverable, testable Bash scripts
ISC License
95 stars 16 forks source link

Add ability to handle go-script output #233

Open nkakouros opened 6 years ago

nkakouros commented 6 years ago

Due diligence

Framework, Bash, and operating system version information

go-script: latest master bash: 4.4.14 Arch linux

Description

In my custom commands, I call a lot of external commands, from apt-get to ansible. I want to have control over command output in order to present to users of my scripts only information that is useful. For instance, they don't care about apt-get output. But they do care about some informational messages that I am echo-ing at some points in the code.

On a custom command level, I can implement the desired behavior by redirecting output of each command that I want to silence to /dev/null. But if there are many commands in a script and, even more importantly, many custom scirpts, it is cumbersome to do that each and every time.

Before moving to go-script-bash, I would do the following at the beginning of my entry-script which would apply to all of the rest of my scripts:

exec 3>&1                                                                                                                                                                          
STDOUT=3                                                                                                                                                                                         
exec 4>&2                                                                                                                                                                          
STDERR=4                                                                                                                                                                            
exec >/dev/null

and have these functions to output my informational messages:

function info() {
  echo "$1" >&${STDOUT}
}
function abort() {
  echo "$1" >&${STDERR}
}

If I do the above while using the go-script, the downside is that all output from go-script, eg help text, autocompletions, etc, are sent to /dev/null.

It would be nice to have go-script redirect its output. There could be a @go.stdout_set function that does:

function @go.stdout() {
  exec 3>&1
}

and go-script outputs to &3. The descriptor could also be in a variable.

Another approach, much slower but more nice-looking to me would be to redirect output to a function that by default simply prints the arguments. Eg:

function -() {
  # for stdout
  echo "$1"
}
function =() {
  # for stderr 
  echo $1 >&2
}

This would need to add a > >(-) after echo's/@go.printf's/... in the code.

In both cases, the user can override these functions and format/edit/silence/... go-script output. Plus, &1 and &2 are left to the user to do however they please (in my case silence them).

If you find this useful, I could implement either of the two approaches.

mbland commented 6 years ago

Yes, this is a great idea, which I can appreciate now that I grok fd 3 in Bats. I'd also vote for the first approach, and documenting the specialness of fd 3 (since, per the linked issue, Bash < 4.1 can't use a variable to redirect).

Sorry for the delayed responses here and in bats-core/bats-core. Still reeling from the end-of-year crunch and new year's rentry at work.

nkakouros commented 6 years ago

Doing a quick scan of the code, I found ~1000 lines that need to be looked into. This will take a while...