4

Is there any practical difference in debugging using bash -x scriptname.sh or using set -x inside the script and then calling it?

In my personal experience I always use bash -x because that way I don't have to change the script so it's less invasive.

Is there a scenario where bash -x would not fit and just set -x would work?

I came up with these questions because I always see people suggesting set -x when trying to help others to debug and I was wondering why not bash -x scriptname.sh. Is there a technical limitation?

PS: I'm not asking about what the commands do, but I'm asking "how" they do and if one is better than the other.

About what they do:

lucasgrvarela
  • 351
  • 1
  • 4
  • 9
  • 2
    `using set -x in terminal and then calling the script?` it won't work that way – KamilCuk Sep 28 '20 at 23:39
  • @KamilCuk opps.. I will fix. – lucasgrvarela Sep 28 '20 at 23:50
  • @lucasgvarela : Convenience: If you put it for debugging inside the script, you have to use an editor, and if you are done, you have to remove it or comment it out. Doing it from the command line, when running the script, allows you to set it "on the fly". Another difference is that `bash -x` also traces the startupfiles, which are listed in the INVOCATION section in the bash man page. This makes a difference, if you, for instance, also use the options `--login` and/or `-i`. – user1934428 Sep 29 '20 at 06:05

3 Answers3

5

I would also suggest set -x and not bash -x to a user debugging a script.

  • The user fully expects to modify the script to fix the bug, so adding a line is a non-issue.
  • You don't have to know how the user runs their script (it could be via some build script or IDE, and not just ./foo in a terminal)
  • You don't have to confirm the shebang, since #!/bin/bash -eui would require you to instead run bash -euix file and #!/bin/sh would require sh -x file.

But for myself? Yeah, I'd just run bash -x.

that other guy
  • 116,971
  • 11
  • 170
  • 194
2

The main reason to avoid things in the shebang is that strictly a POSIX kernel doesn't have to support more than one argument. So #!/usr/bin/env bash -x may not work (#!/bin/bash -x may, but then you may be using the ancient bash on macOS, for example). (That said, many UNIX-like systems do, in fact, support shebangs with multiple arguments.)

If you're dealing with security or secrets options at the first part of your script, but you want to be able to debug later on, you may want to set +x for the security related section. But, you can always do set -x so that is not a particularly robust reason to avoid bash -x.

kojiro
  • 74,557
  • 19
  • 143
  • 201
  • 2
    Given that OP says they don't have to modify the script, I'm guessing they're asking about running `bash -x myscript` and not adding `-x` to the shebang – that other guy Sep 28 '20 at 23:47
  • 2
    Also arguments within the Shebang will be by-passed by direct invocation by the interpreter like `bash scriptname`. So having `set -x` within the script or any other shell option, warrant the option will be set as intended, regardless if the script interpreter is called from the shebang or direct invocation. – Léa Gris Sep 28 '20 at 23:47
1

They are different interface to the same functionality, check out the docs:

All of the single-character options used with the set builtin (see The Set Builtin) can be used as options when the shell is invoked.

The different is. Do I set it before the first line of the script gets evaluated (bash -x ./script.sh), or do I set it within the script (set -x anywhere in the script). They can both enable and disable the simple trace funvtionality, last set "wins" as in affects the lines that follow. There is no functional difference in the effect the two have otherwise.

Ondrej K.
  • 8,841
  • 11
  • 24
  • 39