1

When I set a DEBUG trap in Bash like this:

set -o functrace
trap 'echo "# $BASH_COMMAND" >&2' DEBUG

Suddenly, this function stopped working:

getBase() {

  local base="$1"

  base=$(basename "${base%%\?*}")
  : "${base//+/ }"; printf -v base '%b' "${_//%/\\x}"
  base=$(echo "$base" | sed -e 's/[^A-Za-z0-9._-]/_/g')

  echo "$base"

  return 0
}

with the error

line 6: printf: missing hex digit for \x

and outputs ".__printf_-v_base____________x__x__" to the variable.

I am trying to understand why this is. As the DEBUG trap outputs everything to STDERR, so how can it influence the printf -v function? And how can I solve it?

5
  • is set -e set? what is the output of echo $- in the script? Commented Oct 2 at 12:07
  • Pleases edit your question to show a minimal reproducible example, not just a standalone function and a couple of additional lines. Make sure to run it through shellcheck.net first. Commented Oct 2 at 12:18
  • 1
    also, fyi, just set set -x, it does like exactly the same as your trap command Commented Oct 2 at 12:20
  • @KamilCuk With set -x this bug does not occur, so it can't be exactly the same. Commented Oct 2 at 15:29
  • @EdMorton I created a generic reproducable example, but then I noticed that the question already received an answer. So if I edit my question now with the generic example, the accepted answer does not make any sense anymore. Commented Oct 2 at 15:30

1 Answer 1

2

You use the special variable _ (underscore) for moving the result of ${base//+/ } across commands but the DEBUG trap changes its value to something else. Define getBase like this instead and it'll work:

getBase() {
    local base
    base=${1%%\?*}
    base=${base%"${base##*[!/]}"}
    base=${base##*/}
    base=${base//+/ }
    base=${base//%/\\x}
    printf -v base '%b' "$base"
    base=${base//[!A-Za-z0-9._-]/_}
    printf '%s\n' "$base"
}
Sign up to request clarification or add additional context in comments.

1 Comment

Well done! ( I like base=${base%"${base##*[!/]}"} !), but as //[!A-Za-z0-9._-]/_, the step base=${base//+/ } is useless!! (both space and plus sign + will be converted into underscore _ ;-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.