4

I write a bash script with a --verbose option, where I want to write most lines before I execute them

xinput --set-prop "$TP" "Device Accel Constant Deceleration" $TOUCHPAD_DECELERATION

I would like to have exactly that output with quotes but the variables execuded, so the user can copy and paste that command to execute it again.

This would be the (more and more complicated, if there are a lot of quotes in the command) workaround with writing the line twice:

echo 'xinput --set-prop "'"$TP"'" "Device Accel Constant Deceleration" '"$TOUCHPAD_DECELERATION"
xinput --set-prop "$TP" "Device Accel Constant Deceleration" $TOUCHPAD_DECELERATION

How can I write the outcome ot this line with echo without having to write twice?

2 Answers 2

8

You can use the set -x option. set -x will:

Print a trace of simple commands, for commands, case commands, select commands, and arithmetic for commands and their arguments or associated word lists after they are expanded and before they are executed. The value of the PS4 variable is expanded and the resultant value is printed before the command and its expanded arguments.

If you write:

set -x
var="Hello world"
echo "I say: " $var

then the output will be:

+ var='Hello world'
+ echo 'I say:' Hello world
I say: Hello world

The + is the value of PS4. To suppress it, add PS4= after your set -x line, or change it by setting PS4 to another value.

set -x can also be enabled with set -o xtrace. To disable the option again, use set +x.

If there are only some commands you want to print out, you can run them in a subshell:

( set -x ; echo "I say: " $var )
+ echo 'I say:' Hello world
I say: Hello world

Putting the command in parentheses will apply set -x just for this command, and disable it automatically at the end.

6
  • That sounds nice, but How do you combine this with if [ $VERBOSE ]; So it is only printed out, if --verbose is called?
    – rubo77
    Jul 4, 2014 at 10:25
  • @rubo77 just put the set -x within the if block: if [ $VERBOSE ]; then set -x; fi or, better, $VERBOSE && set -x.
    – terdon
    Jul 4, 2014 at 10:31
  • ok, and then put a set +x after each of those lines
    – rubo77
    Jul 4, 2014 at 10:40
  • @rubo77 no. You only need to do it once, at the start of your script.
    – terdon
    Jul 4, 2014 at 10:42
  • If I would put set -x at the top, then the whole script will be printed out while executed, which is far too much. Only some lines should be verbose, so stopping with set +x is great, only a drawback, that it also prints out this last command: + set +x
    – rubo77
    Jul 4, 2014 at 10:54
2

I use a function for things like this:

#########################################################
# Function to facilitate printing of commands being run #
#########################################################
runthis(){
    echo "$@" 1>&2
    eval "$@"
}

Now, whenever I want to run a command in my script, I run it like this

runthis xinput --set-prop \"$TP\" \"Device Accel Constant Deceleration\" \"$TOUCHPAD_DECELERATION\"
8
  • It doesn't quote parameters, so "Device Accel Constant Deceleration" will become four separate arguments if you copy and paste it. Jul 4, 2014 at 10:08
  • @MichaelHomer no it won't. Note that I am passing that string quoted and so, since "$@" is also quoted, it will be treated as a single argument. You can test this by adding for i in "$@"; do echo "$i"; done in the function. You might also want to read What is the difference between $* and $@?.
    – terdon
    Jul 4, 2014 at 10:15
  • It outputs (say) xinput --set-prop hello Device Accel Constant Deceleration this is a test. There are no quotes in the output to be copy-pasted (although echo does get them as single arguments because it's $@, yes). Jul 4, 2014 at 10:16
  • @MichaelHomer ah, yes you're quite right. I had missed the part of the question that explained that the objective was to copy/paste the command. Bugger, that complicates things, I was forced to use eval.
    – terdon
    Jul 4, 2014 at 10:29
  • Ah I see, you need to add backslashes in the call everywhere then, ok.
    – rubo77
    Jul 4, 2014 at 10:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .