daniels
daniels

Reputation: 19213

How to separate output for each command generated by a bash file?

Let's say we have a bash script like the one bellow:

echo test
ls -alh
pwd
echo test2

So the file can have any number of commands on it each producing or not its own output.

Then the above file is run like this /bin/bash -xe test.sh which will produce the following output:

+ echo test
test
+ ls -alh
total 32
drwx------+  6 daniels  staff   204B Apr  3 23:33 .
drwxr-xr-x+ 64 daniels  staff   2.1K Apr  4 01:53 ..
-rw-r--r--@  1 daniels  staff   6.0K Apr  3 23:33 .DS_Store
drwxr-xr-x   5 daniels  staff   170B Mar 15 17:03 Todo
-rw-r--r--@  1 daniels  staff   282B Apr  3 20:39 test.py
-rw-r--r--@  1 daniels  staff    97B Apr  4 01:52 test.sh
+ pwd
/Users/daniels/Desktop
+ echo test2
test2

Is there any way to parse the generated output reliable and figure out how to separate the output based on each command?

For the above example we should be able to separate and extract one group with:

+ echo test
test

another one with

+ ls -alh
total 32
drwx------+  6 daniels  staff   204B Apr  3 23:33 .
drwxr-xr-x+ 64 daniels  staff   2.1K Apr  4 01:53 ..
-rw-r--r--@  1 daniels  staff   6.0K Apr  3 23:33 .DS_Store
drwxr-xr-x   5 daniels  staff   170B Mar 15 17:03 Todo
-rw-r--r--@  1 daniels  staff   282B Apr  3 20:39 test.py
-rw-r--r--@  1 daniels  staff    97B Apr  4 01:52 test.sh

etc.

I was thinking of parsing the output and look if the line starts with + then take that as the start of one command but then you can easily have something like echo + ok which will make this logic fail.

Another option would've been if we can modify the char that is outputted by /bin/bash -x so that instead of + to output something like https://en.wikipedia.org/wiki/Delimiter#ASCII_delimited_text but looks like + is hardcoded in bash and not configurable.

Any ideas?

Upvotes: 3

Views: 303

Answers (1)

that other guy
that other guy

Reputation: 123510

+ is not hard-coded, and this is readily described in man bash and under help set for -x:

  -x      After expanding each simple command, for  command,
          case  command,  select  command, or arithmetic for
          command, display the expanded value of  PS4,  fol‐
          lowed by the command and its expanded arguments or
          associated word list.

And here's a further description of PS4, also from man bash:

   PS4    The value of this parameter is expanded as  with  PS1  and
          the  value  is  printed  before each command bash displays
          during an execution trace.  The first character of PS4  is
          replicated  multiple times, as necessary, to indicate mul‐
          tiple levels of indirection.  The default is ``+ ''.

Here's an example:

$ PS4=$'\nAnd now, a word from '; set -x; date; uptime

And now, a word from date
Mon Apr  3 16:20:35 PDT 2017

And now, a word from uptime
 16:20:35 up 65 days,  1:24,  6 users,  load average: 1.20, 1.42, 1.37

You can use this to embed special markers or characters as you see fit.

Upvotes: 7

Related Questions