How to silently disable xxtrace in a shell script?

I am writing a shell script that iterates over some values โ€‹โ€‹and runs a long command line for each value. I would like to print these commands along the way, just like make when I run the makefile. I know that I can simply โ€œdrive awayโ€ all the commands before running them, but it feels inelegant. So I look at set -x and similar mechanisms:

 #!/bin/sh for value in a long list of values do set -v touch $value # imagine a complicated invocation here set +v done 

My problem is this: at each iteration, not only the printed line is output, but also the set +x . How can this be prevented? If not, what workaround do you recommend?

PS: MWE above uses sh , but I also have bash and zsh if that helps.

+6
source share
4 answers

Sandbox in a subshell:

 (set -x; do_thing_you_want_traced) 

Of course, changes to the variables or environment made in this subshell will be lost.

If you REALLY care about this, you can also use the DEBUG hook (using set -T to force it to be inherited by functions) to implement the native equivalent of set -x .

For example, if bash is used:

 trap_fn() { [[ $DEBUG && $BASH_COMMAND != "unset DEBUG" ]] && \ printf "[%s:%s] %s\n" "$BASH_SOURCE" "$LINENO" "$BASH_COMMAND" return 0 # do not block execution in extdebug mode } trap trap_fn DEBUG DEBUG=1 # ...do something you want traced... unset DEBUG 

However, emitting BASH_COMMAND (as the DEBUG trap can do) is not completely equivalent to set -x ; for example, it does not show values โ€‹โ€‹after expansion.

+8
source

You want to try using a single-line xxtrace:

 function xtrace() { # Print the line as if xtrace was turned on, using perl to filter out # the extra colon character and the following "set +x" line. ( set -x # Colon is a no-op in bash, so nothing will execute. : " $@ " set +x ) 2>&1 | perl -ne 's/^[+] :/+/ and print' 1>&2 # Execute the original line unmolested " $@ " } 

The original command is executed in the same shell when converting identity. Before starting, you get a non-recursive xxtrace argument. This allows you to keep track of the teams you care about without sending spammers with duplicate copies of each echo command.

 # Example for value in $long_list; do computed_value=$(echo "$value" | sed 's/.../...') xtrace some_command -x -y -z $value $computed_value ... done 
+3
source

I'm thinking of

  set -x >/dev/null 2>1; echo 1; echo 2; set +x >/dev/null 2>&1 

but got

 + echo 1 1 + echo 2 2 + 1> /dev/null 2>& 1 

I am surprised by these results ..... But

 set -x ; echo 1; echo 2; set +x + echo 1 1 + echo 2 2 

will meet your requirements.

I saw similar results when I put each statement in its only line (except for + x)

IHTH.

+1
source

The following command disables the xtrace option:

$ set + o xtrace

0
source

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


All Articles