Bash: capture output set -v

How many times have you seen someone try to "Write the command that I run and the output of the command"? This often happens, and for viewing, the command you are working with set -v is good, ( set -x is nice too, but it can be harder to read), but what happens when you want to capture an executable command ... but not all commands run

Launch interactively. I see no way to write the output of set -v .

 set -v echo a 1>/dev/null # 'echo a 1>/dev/null' is printed to the screen echo a 2>/dev/null # 'echo a 2>/dev/null\na' is printed to the screen 

I can put this in a script and things will get better:

 echo 'set -v'$'\n''echo a' > setvtest.sh bash setvtest.sh 1>/dev/null # 'echo a' is printed to the screen bash setvtest.sh 2>/dev/null # 'a' is printed to the screen 

Aha, so from the script it goes to stderr. What about inline?

 set +v { set -v ; echo a ; } 1>/dev/null # no output set +v ( set -v ; echo a ; ) 1>/dev/null # no output 

Hmm, no luck.

Interestingly, as a side note, this does not yield a solution:

 echo 'set -v ; echo a' > setvtest.sh bash setvtest.sh 1>/dev/null 

I am not sure why, but, perhaps, therefore, why the subshell version does not return anything.

What about shell functions?

 setvtest2 () { set -v echo a } setvtest2 # 'a' set +v setvtest2 1>/dev/null # nothing set +v setvtest2 2>/dev/null # nothing 

Now the question is: Is there a good way to capture the output of set -v ?

Here is my bad hack, so I'm looking for something less crazy:

 #!/usr/bin/env bash script=/tmp/$$.script output=/tmp/$$.out echo 'set -v'$'\n'"$1" >"$script" bash "$script" 1>"$output" cat "$output" rm -f "$script" "$output" 

Now I can execute simple scripts

 bash gen.sh 'echo a' 1>/dev/null # prints 'echo a' bash gen.sh 'echo a' 2>/dev/null # prints 'a' 

But of course there are better ways.

+4
source share
2 answers

You can run bash with the -v option instead of turning it on and off with set :

 bash -v -c "echo a" 1>/dev/null # prints 'echo a' bash -v -c "echo a" 2>/dev/null # prints 'a' 

The dark side of this solution is that each such line will require the creation of a new bash process, but you will not have to forget to disable the v parameter, since it is included only in the child process.

+4
source

What about

 #!/bin/bash set -o xtrace Stuff..... 
+1
source

Source: https://habr.com/ru/post/1402949/


All Articles