Commit 224e0868 authored by Pierre Smeyers's avatar Pierre Smeyers
Browse files

docs(shell): change introduction chapter

parent b903aa61
Loading
Loading
Loading
Loading
Loading
+12 −24
Original line number Diff line number Diff line
@@ -5,36 +5,24 @@ description: This page gives guidelines and recommandations for shell scripting

# Shell Scripting Guidelines

This page gives guidelines and recommandations for shell scripting developement in _to be continuous_.
This page gives guidelines and recommandations for shell scripting developement in _to-be-continuous_.

## Introduction

_to be continuous_ templates bring a lot of magic. All this magic is mainly implemented with shell scripts.
Fine! But which kind of shell are we talking about? Is it Bash? Regular C Shell? Something else?
In _to-be-continuous_, a significant part of the automation is implemented using **shell scripts**. 
These scripts do not rely on a proprietary language or exotic tooling; instead, they use the standard command language available on most Unix-like systems, which is ubiquitous in CI/CD environments and container images.

All TBC template scripts are run in container images inheriting one of the three following base images:
In practice, TBC scripts must be **executable in a wide range of system contexts** - from lightweight Alpine Linux images to more feature-rich Debian or Fedora-based images. A key aspect of our approach is therefore to remain compatible with the most common shells while maximizing script portability and robustness.

```mermaid
---
config:
  pie:
    textPosition: 0.6
  themeVariables:
    pieOuterStrokeWidth: "3px"
---
pie
    "Alpine (Ash shell)" : 65
    "Debian (Bash shell)" : 30
    "Fedora (Bash shell)" : 5
```
On Alpine images (which are widely used for lightweight CI jobs), the default shell is [Ash](https://en.wikipedia.org/wiki/Almquist_shell) (the Almquist Shell), a minimalist shell that closely follows the POSIX specification. On Debian or Fedora images, the shell is typically [Bash](https://www.gnu.org/software/bash/manual/bash.html), which provides many additional features while still supporting the POSIX shell syntax.

> [!note]
> TBC will never try to be compliant with other base images than Alpine, Debian or Fedora, and should never make strong assumptions 
> on wich base image is used in such or such template (because users might always override the default provided images with their own, and TBC should keep working).
The purpose of this page is to clarify **which subset of Bash features can be safely used in Ash**, so that scripts written for _to-be-continuous_ remain both **portable** and **maintainable**, regardless of the execution environment.

As a conclusion: **_to be continuous_ template scripts must be executable with [Bash](https://www.gnu.org/software/bash/manual/bash.html) and [Ash](https://en.wikipedia.org/wiki/Almquist_shell)**.
In the following sections, you will find:

Fortunately, [Ash](https://en.wikipedia.org/wiki/Almquist_shell) is a subset of [Bash](https://www.gnu.org/software/bash/manual/bash.html) so all we have to do is to determine which Bash features are supported in Ash, and which aren't. That's the very purpose of this page.
- a reference of Bash features supported by ash,
- general recommendations for writing robust shell scripts in the TBC context,
- common pitfalls to avoid (notably around shell options and external command usage).

## Bash features support in Ash

@@ -93,7 +81,7 @@ Fortunately, [Ash](https://en.wikipedia.org/wiki/Almquist_shell) is a subset of

### Shell options

All _to be continuous_ templates must use the following [shell options](https://www.gnu.org/software/bash/manual/bash.html#The-Set-Builtin):
All _to-be-continuous_ templates must use the following [shell options](https://www.gnu.org/software/bash/manual/bash.html#The-Set-Builtin):

- `set -e`: instructs bash to immediately exit if any command has a non-zero exit status
- `set -o pipefail`: prevents errors in a pipeline from being masked. If any command in a pipeline fails, the pipeline breaks and that return code is used as the return code of the whole pipeline.
@@ -151,7 +139,7 @@ $ [[ "test" == "te"* ]]; echo $?

:information_source: this is specific to Alpine Ash, the above behavior is not reproduced in Debian or Fedora Bash.

As a conclusion: **glob patterns should never be used for pure string matching** in _to be continuous_ template scripts.
As a conclusion: **glob patterns should never be used for pure string matching** in _to-be-continuous_ template scripts.
Instead, prefer using the regex operator.

The above script can be implemented with the [regex operator](https://www.gnu.org/software/bash/manual/bash.html#index-_005b_005b) (`=~`):