matejak / argbash

Bash argument parsing code generator
Other
1.39k stars 63 forks source link

ANSI colour escape codes crash argbash parser #156

Closed gdevenyi closed 1 year ago

gdevenyi commented 3 years ago

I was integrating some of the pretty printing functions from https://github.com/kvz/bash3boilerplate/blob/master/main.sh in my project when I found that argbash could no longer re-parse the template and generate a new set of parsing code.

$ argbash -i myscript.sh
/usr/bin/m4:stdin:370: ERROR: end of file in string
autom4te: /usr/bin/m4 failed with exit status: 1
You seem to have an unmatched square bracket on line 340:
        # [ <-- needed because of Argbash
Error during autom4te run, aborting!

I have narrowed it down to this reproducer using the simple argbash template example surrounding it:

#!/bin/bash
#
# This is a rather minimal example Argbash potential
# Example taken from http://argbash.readthedocs.io/en/stable/example.html
#
# ARG_OPTIONAL_SINGLE([option], [o], [optional argument help msg])
# ARG_OPTIONAL_BOOLEAN([print], , [boolean optional argument help msg])
# ARG_POSITIONAL_SINGLE([positional-arg], [positional argument help  msg], )
# ARG_HELP([The general script's help msg])
# ARGBASH_GO

# [ <-- needed because of Argbash

function __b3bp_log() {
  local log_level="${1}"
  shift

  while IFS=$'\n' read -r log_line; do
    echo -e "$(date -u +"%Y-%m-%d %H:%M:%S UTC") "\\x1b[1;37;41m"$(printf "[%9s]" "${log_level}")${color_reset} ${log_line}" 1>&2
  done <<<"${@:-}"
}

# ] <-- needed because of Argbash

Which crashes the parser

$ argbash -i example.sh
/usr/bin/m4:stdin:42: ERROR: end of file in string
autom4te: /usr/bin/m4 failed with exit status: 1
You seem to have an unmatched square bracket on line 12:
        # [ <-- needed because of Argbash
Error during autom4te run, aborting!
gdevenyi commented 3 years ago

Actually, here's an even smaller reproducer:

#!/bin/bash
#
# This is a rather minimal example Argbash potential
# Example taken from http://argbash.readthedocs.io/en/stable/example.html
#
# ARG_OPTIONAL_SINGLE([option], [o], [optional argument help msg])
# ARG_OPTIONAL_BOOLEAN([print], , [boolean optional argument help msg])
# ARG_POSITIONAL_SINGLE([positional-arg], [positional argument help  msg], )
# ARG_HELP([The general script's help msg])
# ARGBASH_GO

# [ <-- needed because of Argbash

 local color_debug="\\x1b[35m"

# ] <-- needed because of Argbash

Looks like the parser doesn't like bash colour codes.

emilheunecke commented 3 years ago

https://argbash.readthedocs.io/en/stable/index.html#limitations

The square brackets in your script have to match (i.e. every opening square bracket [ has to be followed at some point by a closing square bracket ]).

There is a workaround — if you need constructs s.a. red=$'\e[0;91m', you can put the matching square bracket behind a comment, i.e. red=$'\e[0;91m' # match square bracket: ].

So you can simply add a comment as such

#!/bin/bash
#
# This is a rather minimal example Argbash potential
# Example taken from http://argbash.readthedocs.io/en/stable/example.html
#
# ARG_OPTIONAL_SINGLE([option], [o], [optional argument help msg])
# ARG_OPTIONAL_BOOLEAN([print], , [boolean optional argument help msg])
# ARG_POSITIONAL_SINGLE([positional-arg], [positional argument help  msg], )
# ARG_HELP([The general script's help msg])
# ARGBASH_GO

# [ <-- needed because of Argbash

 local color_debug="\\x1b[35m" #]

# ] <-- needed because of Argbash
gdevenyi commented 3 years ago

Thanks for the reference. It's nice and all, but it doesn't solve the issue that I didn't know to look there when the parser crashed :+1:

matejak commented 1 year ago

This is a technical limitation of the underlying technology. I know that this is a pain, and sorry for that, it is at least on the first page of the documentation under section Limitations.