Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make scripts/library.sh work for Bash v3 #2143

Closed
rhuss opened this issue Jun 2, 2020 · 15 comments
Closed

Make scripts/library.sh work for Bash v3 #2143

rhuss opened this issue Jun 2, 2020 · 15 comments

Comments

@rhuss
Copy link
Contributor

rhuss commented Jun 2, 2020

When including scripts/library.sh with Bash v3 (which is the version used on macOS), you get the following errors:

scripts/test-infra/library.sh: line 29: conditional binary operator expected
scripts/test-infra/library.sh: line 29: syntax error near `GOPATH'
scripts/test-infra/library.sh: line 29: `if [[ ! -v GOPATH ]]; then'

It would be good if the script would be runnable on a POSIX compliant shell, or at least Bash v3 and do not use Bash v4 or v5 only features. The use case is, that it is desirable to reuse library functions like update_licenses or remove_broken_symlinks not only for CI/CD where you have control of the environment but also in build scripts and/or make files to be run on developer machines where you do not have control of what is installed by default, but still want to have the least extra dependencies to be installed by a developer (like we for build.sh from the client repository which is supposed to run on a POSIX system (not only in shell syntax, but also what features to use from which UNIX tool).

Being passive in shell scripting (i.e. using the least common denominator across shells/versions) is generally a good advise, as one of the main motivation to use shell instead e.g. a real programming language like Python or Perl is that it ubiquitous available (and not because shell coding is so much fun :)

@rhuss
Copy link
Contributor Author

rhuss commented Jun 8, 2020

@chizhg @chaodaiG any thoughts on this ? If there is a commitment to stick to bash v3, I'm happy to help and work on a PR to switch to bash v3 features only.

@chizhg
Copy link
Member

chizhg commented Jul 14, 2020

@chizhg @chaodaiG any thoughts on this ? If there is a commitment to stick to bash v3, I'm happy to help and work on a PR to switch to bash v3 features only.

Sorry for the late reply on this, I agree we should stick to bash v3 to make it runnable for most of our users, so please feel free to start the PR to switch to bash v3 features only.

Thanks!

@coryrc
Copy link
Contributor

coryrc commented Aug 10, 2020

I don't agree, because these v4 features help make the scripts more robust. The scripts already use #!/usr/bin/env bash so Mac users can install a version of bash from this millenium.

@chizhg
Copy link
Member

chizhg commented Aug 10, 2020

I'm not familiar with the bash v3 equivalent features for the v4 syntaxes like [[ ! -v GOPATH ]], will it be adding much more complexities?

@coryrc
Copy link
Contributor

coryrc commented Aug 10, 2020

The main additions affecting us are improved handling of arrays and miscellaneous features, like the above, that make the user's intention clearer.

https://mywiki.wooledge.org/BashFAQ/061

bash 4.0 was released in 2009. bash 3.2 in 2006. This is solely a problem because Apple refuses to ship CLI software with GPL3. Every developer should have homebrew installed because their entire CLI is frozen at 2007.

@dprotaso
Copy link
Member

It seems like the only bash v4 usage is the [[ -v VAR ]] flag which seems like there's a suitable bash v3 work around [[ -z ${VAR+x} ]]

We should probably have @knative/technical-oversight-committee chime in as this spans the entire project and we should be consistent one way or the other

@dprotaso
Copy link
Member

if bash 4 is the way we want to go is there a way to have the scripts fail immediately if it's not installed

ie. is there something like #!/usr/bin/env bash --version=4 at the top of each script

@chizhg
Copy link
Member

chizhg commented Aug 14, 2020

It looks we could check the value of BASH_VERSINFO and exit if it's smaller than 4 - https://askubuntu.com/a/916978

@chizhg
Copy link
Member

chizhg commented Aug 14, 2020

if [ -z "${BASH_VERSINFO}" ] || [ -z "${BASH_VERSINFO[0]}" ] || [ ${BASH_VERSINFO[0]} -lt 4 ]; then
  echo "This script requires Bash version >= 4"
  exit 1 
fi

seems to be safer.

@coryrc
Copy link
Contributor

coryrc commented Aug 14, 2020

We could throw it in library.sh which should catch most scripts

@rhuss
Copy link
Contributor Author

rhuss commented Aug 30, 2020

If insisting to use a script interpreter (like bash v4 on mac) to run the scripts I don't understand why then using something that is so fragile and untestable like shell for scripting and not a real programming language like Python or even Perl. IMO the only reason for using shell is that it is ubiquitously available on every UNIX like system and works everywhere (that's why I typically would also not even require Bash, but any shell should do it). That's the only point, and if you like to use 'advanced' features like proper array support then a real language should be used imo (which Bash v4 is not).

Many of the Bash V4 concepts that are used in library.sh can be easily simulated for older shell versions (does not even need to be Bash), like avoiding -v, with the additional benefit that basic shell knowledge is sufficient to read the scripts (and there is no need to look up or learn Bash v4 special behaviours).

Said that failing fast as @chizhg suggest would be definitely a step forward.

@rhuss
Copy link
Contributor Author

rhuss commented Aug 30, 2020

bash 4.0 was released in 2009. bash 3.2 in 2006.

compared to the age of UNIX shell itself, this is just yesterday :)

@coryrc
Copy link
Contributor

coryrc commented Aug 30, 2020

why then using something that is so fragile and untestable like shell for scripting

I'm working on replacing it!

@jsoref
Copy link

jsoref commented Oct 28, 2020

@coryrc: minor point: this millennium started in 2001 which is well before 2006. The only applicable term would be decade, but neither version of Bash was released between 2011 and 2020.

Speaking as a beard wearer 🧔 who started using the internet/Unix/Linux/Bash in the previous millennium.

@rhuss
Copy link
Contributor Author

rhuss commented Nov 12, 2020

Closing this as the hard bash v4 dependency won't change I suspect (and if the build system changes towards go then its not worth the hassle either)

Added the hard requirement on bash v4 to the client build script.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants