Giter Site home page Giter Site logo

bash3boilerplate's Introduction

Overview

When hacking up Bash scripts, there are often things such as logging or command-line argument parsing that:

  • You need every time
  • Come with a number of pitfalls you want to avoid
  • Keep you from your actual work

Here's an attempt to bundle those things in a generalized way so that they are reusable as-is in most scripts.

We call it "BASH3 Boilerplate" or b3bp for short.

Goals

Delete-Key-Friendly. Instead of introducing packages, includes, compilers, etc., we propose using main.sh as a base and removing the parts you don't need. While this may feel a bit archaic at first, it is exactly the strength of Bash scripts that we should want to embrace.

Portable. We are targeting Bash 3 (OSX still ships with 3, for instance). If you are going to ask people to install Bash 4 first, you might as well pick a more advanced language as a dependency.

Features

  • Conventions that will make sure that all your scripts follow the same, battle-tested structure
  • Safe by default (break on error, pipefail, etc.)
  • Configuration by environment variables
  • Simple command-line argument parsing that requires no external dependencies. Definitions are parsed from help info, ensuring there will be no duplication
  • Helpful magic variables like __file and __dir
  • Logging that supports colors and is compatible with Syslog Severity levels, as well as the twelve-factor guidelines

Installation

There are three different ways to install b3bp:

Option 1: Download the main template

Use curl or wget to download the source and save it as your script. Then you can start deleting the unwanted bits, and adding your own logic.

wget https://bash3boilerplate.sh/main.sh
vim main.sh

Option 2: Clone the entire project

Besides main.sh, this will also get you the entire b3bp repository. This includes a few extra functions that we keep in the ./src directory.

git clone [email protected]:kvz/bash3boilerplate.git

Option 3: Require via npm

As of v1.0.3, b3bp can also be installed as a Node module, meaning you can define it as a dependency in package.json via:

npm init
npm install --save --save-exact bash3boilerplate

Even though this option introduces a Node.js dependency, it does allow for easy version pinning and distribution in environments that already have this prerequisite. This is, however, entirely optional and nothing prevents you from ignoring this possibility.

Changelog

Please see the CHANGELOG.md file.

Frequently Asked Questions

Please see the FAQ.md file.

Best practices

As of v1.0.3, b3bp offers some nice re-usable libraries in ./src. In order to make the snippets in ./src more useful, we recommend the following guidelines.

Function packaging

It is nice to have a Bash package that can not only be used in the terminal, but also invoked as a command line function. In order to achieve this, the exporting of your functionality should follow this pattern:

if [[ "${BASH_SOURCE[0]}" = "${0}" ]]; then
  my_script "${@}"
  exit $?
fi
export -f my_script

This allows a user to source your script or invoke it as a script.

# Running as a script
$ ./my_script.sh some args --blah
# Sourcing the script
$ source my_script.sh
$ my_script some more args --blah

(taken from the bpkg project)

Scoping

  1. In functions, use local before every variable declaration.
  2. Use UPPERCASE_VARS to indicate environment variables that can be controlled outside your script.
  3. Use __double_underscore_prefixed_vars to indicate global variables that are solely controlled inside your script, with the exception of arguments that are already prefixed with arg_, as well as functions, over which b3bp poses no restrictions.

Coding style

  1. Use two spaces for tabs, do not use tab characters.
  2. Do not introduce whitespace at the end of lines or on blank lines as they obfuscate version control diffs.
  3. Use long options (logger --priority vs logger -p). If you are on the CLI, abbreviations make sense for efficiency. Nevertheless, when you are writing reusable scripts, a few extra keystrokes will pay off in readability and avoid ventures into man pages in the future, either by you or your collaborators. Similarly, we prefer set -o nounset over set -u.
  4. Use a single equal sign when checking if [[ "${NAME}" = "Kevin" ]]; double or triple signs are not needed.
  5. Use the new bash builtin test operator ([[ ... ]]) rather than the old single square bracket test operator or explicit call to test.

Safety and Portability

  1. Use {} to enclose your variables. Otherwise, Bash will try to access the $ENVIRONMENT_app variable in /srv/$ENVIRONMENT_app, whereas you probably intended /srv/${ENVIRONMENT}_app. Since it is easy to miss cases like this, we recommend that you make enclosing a habit.
  2. Use set, rather than relying on a shebang like #!/usr/bin/env bash -e, since that is neutralized when someone runs your script as bash yourscript.sh.
  3. Use #!/usr/bin/env bash, as it is more portable than #!/bin/bash.
  4. Use ${BASH_SOURCE[0]} if you refer to current file, even if it is sourced by a parent script. In other cases, use ${0}.
  5. Use :- if you want to test variables that could be undeclared. For instance, with if [[ "${NAME:-}" = "Kevin" ]], $NAME will evaluate to Kevin if the variable is empty. The variable itself will remain unchanged. The syntax to assign a default value is ${NAME:=Kevin}.

Who uses b3bp?

We are looking for endorsements! Are you also using b3bp? Let us know and get listed.

Authors

License

Copyright (c) 2013 Kevin van Zonneveld and contributors. Licensed under MIT. You are not obligated to bundle the LICENSE file with your b3bp projects as long as you leave these references intact in the header comments of your source files.

bash3boilerplate's People

Contributors

dependabot[bot] avatar eval avatar filipbrinkmann avatar gdevenyi avatar gmasse avatar gmeral avatar jokajak avatar kvz avatar lukasstockner avatar mathieu-aubin avatar mstreuhofer avatar qwertyzw avatar rasa avatar rfuehrer avatar roo-shy avatar rouson avatar warpengineer avatar zbeekman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bash3boilerplate's Issues

Website

I had the idea to create a simple website for this under e.g. the bash3boiletplate.sh domain name using GitHub pages. As a first iteration it would render the README.md to HTML so it could serve as a simple single front page. But I feel it would give the project some more substance, what do you think?

Configuration files

This is a feature request.

Having the script automatically parse some sort of configuration file (json,xml,yaml,bash) that dictates default values for its arguements would nice.

Why not just use default parameters?

Assume a case where the scripts are written for a multitude of runtimes (say for e.g; servers) and the default parameters are meant to be different for each runtime.

FAQ or User Guide?

It would be great to have a FAQ or User Guide describing some common use cases. I'd like to know how to add a new command-line flag and have spent at least of couple of hours trying so far. Is there an example somewhere?

Tilde not parsed correctly on arguments as default

I'm testing your script and it is really useful. However, I found one problem, not sure if I am using it wrong or it's actually a bug.

When you use a tilde (~) in paths, it seems that is converted to something else (although when you print it, it looks OK).

For example, take your main and place a file in home (~) and try to access it and all the commands will fail.

[ -f ${arg_t} ] && echo "temp ${arg_t} exist" || echo "temp ${arg_t} does not exist"
stat ${arg_t}

And I set the read block as

-t --temp  [arg] Location of tempfile. Default="~/foo"

But if you set it to something else, without the tilde it works.

Feedback by galaktos

We received feedback by galaktos let's put it to good use!

if [ "${BASH_SOURCE[0]}" != ${0} ]; then

  • Unquoted variable access within [ testsโ€ฆ bad idea.

Use a single equal sign when checking if [ "${NAME}" = "Kevin" ], double or triple signs are not needed in Bash

  • Except that what youโ€™ve just written has nothing to do with Bash โ€“ [ is an external program (the builtin is [[). And the [ a = b ] syntax is specified in POSIX, so Iโ€™d be surprised if any other shell โ€œneededโ€ double or triple equals signs there โ€“ so why even mention this?

Use {} to enclose your variables in. Otherwise Bash will try to access the $ENVIRONMENT_app variable in /srv/$ENVIRONMENT_app, whereas you probably intended /srv/${ENVIRONMENT}_app.

  • Sure, in this case you have to use {}. But why use it when itโ€™s not necessary? Thatโ€™s just cluttering the codebase with needless extra symbols.

Use :- if you want to test variables that could be undeclared. For instance: if [ "${NAME:-}" = "Kevin" ] will set $NAME to be empty if itโ€™s not declared instead of throwing an error. You can also set it to noname like so if [ "${NAME:-noname}" = "Kevin" ]

  • No, this will not set the variable. It will evaluate to that value if the variable is empty, but the variable itself will remain unchanged. The syntax to assign a default value is ${parameter:=word}.

Option flag description spanning more than a single line

It would be nice to be able to have better control over the usage statement. In particular:

  • Option flag descriptions spanning more than one line
  • More control over general usage statement formatting and content
  • Additional, non option text, such as usage examples etc.

It's possible that the last point is a non-issue, I need to examine the usage text parsing more carefully.

The first point will need some different usage statement parsing logic. It's possible that some sort of special line break character or string could be used, and then when the usage statement is parsed for options, consecutive lines containing the special character/string would be concatenated, but when the usage statement is printed a line break is inserted at that character. An easy candidate could be \n which when echoed with echo -e would insert a line break. Thoughts?

Not sure what to do about the second point yet...

Redeclaring colors in b3bp_log function

I noticed that the logging colors are defined in the __b3bp_log function and that they are set every time the function is called. Highly unlikely it have a noticeable impact on performance, but debugging stuff is terrible with the overhead. Is it necessary to redeclare them on each call? Of course I can move them outside myself, but if there is a specific reasoning for this structure I would like to hear it.

License main.sh (boiler plate) without attribution requirement?

Hi @kvz,
First of all I want to say, your project is awesome, and you deserve credit, recognition and attribution for it! ๐Ÿ’ฏ However, I am wondering if adopting a CC0 or, IMO less desirable, the unlicense might help promote adoption. Since this is intended to be a boiler plate, it is not clear to me, exactly how and under what conditions the MIT license needs to be preserved and distributed with projects that bootstrap shell scripts with bash3boilerplate. Part of this is my admitted inexperience with software licenses, but I also feel like this is a "ship of Theseus" problem at what point does borrowing components from the script require that the MIT license be included, referenced etc.

I certainly defer to your judgement here, this issue is only intended to prompt discussion and reconsideration of licensing concerns.

Git bash on Windows

The __os variable is set incorrectly on Windows (using git bash). Recommend adding this to the boilerplate.

if [[ "${OSTYPE:-}" == "msys"* ]]; then
__os="Windows"
fi

Style guide?

My sense is that bash3boilerplate has at least two distinct but related goals: (1) provide some useful code that others might copy, paste, and modify/include and (2) demonstrate best practices. Toward the latter end, it would be great to have a style guide that explains come of the choices (and any related tradeoffs) employed in bash3boilerplate codes. Alternatively, style questions could be added to the FAQ, but I think of the FAQ as being more about how to use bash3boilerplate and a Style Guide being about how a user can write their own better bash 3 code. Either way, here are a couple of topics:

  1. Single- vs. double-bracket tests:
    main.sh uses double-bracket tests in some places such and single-bracket tests in other places. For example, line 91 uses both. It would be great to have a style guide that explains such choices.
  2. Curly brace variable evaluation:
    A stack overflow page provides a good explanation of why it's a good practice to always use curly braces when evaluating a variable (e.g., ${foo})

P.S. With a Style Guide, you guys probably would have the beginnings of a great book. :) It probably wouldn't have to be very long (e.g., 25-50 pages) to be useful. In fact, it's probably more useful if it's short and can be devoured quickly. The content could be driven completely by going through bash3boilerplate and detailing the decisions you made at each point in its development.

using color (or not) depending on `-t 1` seems wrong

if [ "${NO_COLOR}" = "true" ] || [[ "${TERM:-}" != "xterm"* ]] || [ -t 1 ]; then

The line

if [ "${NO_COLOR}" = "true" ] || [[ "${TERM:-}" != "xterm"* ]] || [ -t 1 ]; then

seems to be wrong really in at least 2 different ways.

  1. It checks STDOUT to be connected to a terminal while logging happens on STDERR only.
  2. It turns OFF colors if STDOUT is actually connected to a terminal.

I'm guessing here but a quick check seems to suggest that nobody noticed until now because __b3bp_log always got called in a subshell which actually was not connected to a terminal. If the function would be just called - as suggested by shellcheck - the code would not work as expected.

Now I can fix that, but before that I wanted to ask if there is something about this code, or the decisions leading to this code, which I overlooked or I don't understand.

Exiting only on "emergency"

Is it intended that only an "emergency" causes an exit?
I would expect anything above critical should immediately exit.
From the docs:
"Safe by default (break on error, pipefail, etc.)"

Magic variable to detect if script is being sourced

if [[ "${BASH_SOURCE[0]}" != "${0}" ]] ; then
  __being_sourced=true
else
  __being_sourced=false
fi

$__being_sourced && set -o errexit # exit on any errors, so long as we're not sourcing the script, since that would quit

Defaults don't work when using short options strings

This may be the same bug as #5 and I think I have found a fix.... but it's possible they are distinct.

./main.sh -f foo -t should populate arg_t with the value parsed from the usage string default. However, opt is set to ?, the help function is called and getopts aborts.

As detailed on this SO post you can actually put getopts into silent mode an explicitly test for missing option arguments. Here is some more info from bash hackers wiki: http://wiki.bash-hackers.org/howto/getopts_tutorial#error_reporting

This technique will allow b3bp to not barf when optional option arguments are missing.

Odd behaviour when example.sh is invoked with no args

No sure if this behaviour is intended. I'm using bash4. This is what I had to do to work around it: QwertyZW@0cdc704

qwertyzw% ./example.sh       

(18-06-25 6:20:41) <1> [~/bash3boilerplate]  
qwertyzw% PS4='Line ${LINENO}: ' bash -x ./example.sh
Line 31: read -r -d '' __usage
Line 39: true
Line 42: read -r -d '' __helptext
Line 46: true
LLLine 49: dirname ./example.sh
LLine 49: cd .
LLine 49: pwd
Line 49: source /home/alkhishm/bash3boilerplate/main.sh
LLine 19: set -o errexit
LLine 21: set -o errtrace
LLine 23: set -o nounset
LLine 25: set -o pipefail
LLine 29: [[ /home/alkhishm/bash3boilerplate/main.sh != \.\/\e\x\a\m\p\l\e\.\s\h ]]
LLine 30: __i_am_main_script=0
LLine 32: [[ -n x ]]
LLine 33: [[ ./example.sh = \.\/\e\x\a\m\p\l\e\.\s\h ]]
LLine 34: __i_am_main_script=1
LLine 37: __b3bp_external_usage=true
LLine 38: __b3bp_tmp_source_idx=1
LLLLine 47: dirname ./example.sh
LLLine 47: cd .
LLLine 47: pwd
LLine 47: __dir=/home/alkhishm/bash3boilerplate
LLLine 48: basename ./example.sh
LLine 48: __file=/home/alkhishm/bash3boilerplate/example.sh
LLLine 49: basename /home/alkhishm/bash3boilerplate/example.sh .sh
LLine 49: __base=example
LLLine 50: printf %q /home/alkhishm/bash3boilerplate/example.sh
LLLine 50: (( 0 ))
LLine 50: __invocation=/home/alkhishm/bash3boilerplate/example.sh

(18-06-25 6:20:44) <1> [~/bash3boilerplate]  
qwertyzw% git checkout master
Previous HEAD position was 327cba7... Add magic variable that stores the full command line invocation (#99)
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.

(18-06-25 6:20:48) <0> [~/bash3boilerplate]  
qwertyzw% ./example.sh 

 Option -f (--file) requires an argument

  -f --file  [arg] Filename to process. Required.
  -t --temp  [arg] Location of tempfile. Default="/tmp/bar"
  -v               Enable verbose mode, print script as it is executed
  -d --debug       Enables debug mode
  -h --help        This page
  -n --no-color    Disable color output
  -1 --one         Do just one thing

 This is Bash3 Boilerplate's help text. Feel free to add any description of your
 program or elaborate more on command-line arguments. This section is not
 parsed and will be added as-is to the help.

Consider using `[[` by default

As Browsing_From_Work mentioned on https://www.reddit.com/r/programming/comments/4parog/bash3_boilerplate_template_for_writing_better/d4ji2yh there are some good arguments for it. For convenience, the comment also points to this page.

I see a lot of pros, and only a possible con that we might have more explaining to do. But I think we can figure out that part fine. It might also save us some explaining of pitfalls with [

We are already using it in order to do pattern matching to figure out the OS family

Thoughts?

src/templater.sh should be replaced or removed

templater.sh does its magic trying to use sed.
this works out fine as long as there is no surprise in any env var.
this cannot even really be fixed as such because really sed is the wrong tool for this job.
possibly use perl where quoting (\Q and \E) can be used or do as most others suggest and use eval+cat.
or at least try to replace only vars which actually get referenced in the template and live with the fact that if this variable has unexpected content stuff breaks - right now a sed command is issued for each existing env var. this is bound to break no matter what.

opinions? remarks? ideas?

Repeat arguments

Right now, if I want to provide multiple inputs to an argument I have to do this:

-s "arg1 arg2"

It would be nice if it instead could be:

-s arg1 -s arg2

Or possibly,

-s arg1 arg1

Default "on" for flags?

I see examples for setting defaults for arguments with options, what about arguments without options?

Long-form invalid arguments aren't caught

Example:

read -r -d '' __usage <<-'EOF' || true # exits non-zero when EOF encountered
  -s --subject     [arg] Specific subject files to process.
  -v --verbose           Enable verbose mode for all scripts.
  -d --debug             Enables debug mode.
  -h --help              This help page.
  -n --dry-run           Don't submit any jobs.
  -r --reg-command [arg] Provide an alternative registration command. Default="mb_register.sh"
  -f --factor      [arg] Scaling factor for time and memory estimates. Default="1.15"
EOF
read -r -d '' __helptext <<-'EOF' || true # exits non-zero when EOF encountered
  MAGeTBrain implementation using ANTs
  Supports MINC and NIFTI input files (ANTs must be built with MINC support)
  Invocation: mb.sh [options] -- [stage 1] [stage 2] ... [stage N]
  Standard stages: template, subject, resample, vote, run (template, subject, resample, vote)
  Multiatlas stages: multiatlas-resample, multiatlas-vote, multiatlas (template, multiatlas-resample, multiatlas-vote)
  Other stages: init, status, cleanup
  Multiple commands will run multiple stages. Order is not checked.
EOF

User tried to do:

$ mb.sh --template
#Instead of
$ mb.sh -- template

There was no error thrown for the invalid command-line option "--template"

New FAQ question: How do I access a potentially unset environment variable?

I propose the text below as a new FAQ question. If you agree, please feel free to copy, paste, and edit it or let me know if you want me to branch, commit, and submit a pull request.

How do I access a potentially unset environment variable?
The set -o nounset line in main.sh causes error termination when an unset environment variables is detected as unbound. To avoid this, declare all environment variables before use, e.g.,

#!/usr/bin/env bash
# Include main.sh (NOTE: comment final line before executing this script):
. main.sh
declare FOO
# Testing FOO below would cause termination with a non-zero exit code without the above declaration
if [[ -z ${FOO} ]]; then
  info "FOO is empty."
else
  info "FOO has a value"
fi

Continuous Integration

It would be cool to have basic tests ran on Travis CI.
Bonus points for running against multiple bash versions and GNU/BSD tools. Unsure yet how to do that tho.

Add readme example for users on where to add boiler plate code.

I did not realize until after some trial and error that the best place to insert the code within the script is within the function that you want to export. I was having issues with the exporting the function. I think a recommendation within the read me on where to insert the boiler plate code would help others would reduce quick start friction:

#!/usr/bin/env bash

function foo(){
// Boilerplate code
}

#Recommended export code already outlined within the Function Packaging section of the  read me

if [ "${BASH_SOURCE[0]}" != "${0}" ]; then
  export -f foo
else
  foo "${@}"
  exit $?
fi

Throw errors and/or don't consume next option when OPTARG missing

$ LOG_LEVEL=7 /bin/bash -o pipefail -o nounset -o errexit ./main.sh -f -t
2016-02-16 16:27:12 UTC [    debug] cli arg arg_f = () -> -t
2016-02-16 16:27:12 UTC [     info] You are on OSX
2016-02-16 16:27:12 UTC [    debug] Info useful to developers for debugging the application, not useful during operations.
2016-02-16 16:27:12 UTC [     info] Normal operational messages - may be harvested for reporting, measuring throughput, etc. - no action required.
2016-02-16 16:27:12 UTC [   notice] Events that are unusual but not error conditions - might be summarized in an email to developers or admins to spot potential problems - no immediate action required.
2016-02-16 16:27:12 UTC [  warning] Warning messages, not an error, but indication that an error will occur if action is not taken, e.g. file system 85% full - each item must be resolved within a given time. This is a debug message
2016-02-16 16:27:12 UTC [    error] Non-urgent failures, these should be relayed to developers or admins; each item must be resolved within a given time.
2016-02-16 16:27:12 UTC [ critical] Should be corrected immediately, but indicates failure in a primary system, an example is a loss of a backup ISP connection.
2016-02-16 16:27:12 UTC [    alert] Should be corrected immediately, therefore notify staff who can fix the problem. An example would be the loss of a primary ISP connection.
2016-02-16 16:27:12 UTC [emergency] A "panic" condition usually affecting multiple apps/servers/sites. At this level it would usually notify all tech staff on call.
2016-02-16 16:27:12 UTC [     info] Cleaning up. Done

short and long argument name

Hi, and thanks for your work, this is really helpful :)

I have a little question, how would you do for short and long argument name.
Let's say I have an argument filename, and you can either use it with -f or --filename. It is also required.
Would you have a quick way to adapt you boiler plate to fit that?

Thanks a lot again :)

Pierre

using longname args with and without value in the wrong order produces the wrong result

See 9350e05#commitcomment-30019068

This change breaks the following call:
script.sh --long value --switch
The value of arg_l will be "value--switch" instead of "value", and arg_s will not be defined.

Cause is in line 242ff, where OPTIND is advanced by the number in has_arg, which before was either 0 or 1, but now 2 is possible and has a special meaning but also affects this operation: ${@:OPTIND:${!__b3bp_tmp_varname}}

Following calls are unaffected, which is why the tests don't break (insufficient test cases ;)) and may explain why this hasn't been reported yet:
script.sh --switch --long value (only last option has value)
script.sh --long=value --switch (using "long-option=value" syntax)
script.sh -l value --switch (single-character options are unaffected for some reason, though I'm not sure why...)

My personal solution is to use a separate (bool) variable instead of extending the has_arg by another value: _b3bp_tmp_requires_arg${__b3bp_tmp_opt:0:1}

Consider using `((` for int and math expressions

As Vaphell suggests:

on top of what parent said the [[ ]] / (( )) dichotomy is really useful because it allows for 2 visually distinct modes of work which reduces the cognitive cost:
text [[ ]] with patterns regexen and shit
ingeger math (( )) using C syntax lookalike for int math and comparisons.
(( c++ ))
(( x = y + 3 )) # equivalent to x=$(( y + 3 ))
if (( RANDOM%17 == 4 ))
text is assumed to be a variable, so $ can be dropped for additional readability ($ is required only if the > expression is supposed to make use of positional params to disambiguate 1 and $1
[ ] is everything crammed together, using less than stellar switch based syntax.

Perhaps we have use cases already where we want to apply this, if not a deciding on one form and adding that to the README/website would be nice

Latest shellcheck complaints about main.sh

Folks,

It looks like the latest version of shellcheck complains about a few things in main.sh. Maybe SC#### numbers have changed for some of these things that might need to be skipped?

`
$ shellcheck main.sh

In main.sh line 65:
local color_debug="\x1b[35m"
^-- SC1117: Backslash is literal in "\x". Prefer explicit escaping: "\x".

In main.sh line 67:
local color_info="\x1b[32m"
^-- SC1117: Backslash is literal in "\x". Prefer explicit escaping: "\x".

In main.sh line 69:
local color_notice="\x1b[34m"
^-- SC1117: Backslash is literal in "\x". Prefer explicit escaping: "\x".

In main.sh line 71:
local color_warning="\x1b[33m"
^-- SC1117: Backslash is literal in "\x". Prefer explicit escaping: "\x".

In main.sh line 73:
local color_error="\x1b[31m"
^-- SC1117: Backslash is literal in "\x". Prefer explicit escaping: "\x".

In main.sh line 75:
local color_critical="\x1b[1;31m"
^-- SC1117: Backslash is literal in "\x". Prefer explicit escaping: "\x".

In main.sh line 77:
local color_alert="\x1b[1;33;41m"
^-- SC1117: Backslash is literal in "\x". Prefer explicit escaping: "\x".

In main.sh line 79:
local color_emergency="\x1b[1;4;5;33;41m"
^-- SC1117: Backslash is literal in "\x". Prefer explicit escaping: "\x".

In main.sh line 84:
local color_reset="\x1b[0m"
^-- SC1117: Backslash is literal in "\x". Prefer explicit escaping: "\x".

In main.sh line 86:
if [[ "${NO_COLOR:-}" = "true" ]] || ( [[ "${TERM:-}" != "xterm"* ]] && [[ "${TERM:-}" != "screen"* ]] ) || [[ ! -t 2 ]]; then
^-- SC2235: Use { ..; } instead of (..) to avoid subshell overhead.

In main.sh line 252:
((OPTIND+=_b3bp_tmp_has_arg${__b3bp_tmp_opt}))
^-- SC1105: Shells disambiguate (( differently or not at all. For subshell, add spaces around ( . For ((, fix parsing errors.
^-- SC2030: Modification of OPTIND is local (to subshell caused by (..) group).

In main.sh line 269:
shift $((OPTIND-1))
^-- SC2031: OPTIND was modified in a subshell. That change might be lost.

In main.sh line 383:
info "$(echo -e "multiple lines example - line #1\nmultiple lines example - line #2\nimagine logging the output of 'ls -al /path/'")"
^-- SC1117: Backslash is literal in "\n". Prefer explicit escaping: "\n".
^-- SC1117: Backslash is literal in "\n". Prefer explicit escaping: "\n".
`

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.