Improve readme (#725)
- Add section about using `set -euxo pipefail` - Add section about setting variables inside recipes
This commit is contained in:
parent
c4835c8ff1
commit
8502cf6618
57
README.adoc
57
README.adoc
@ -826,6 +826,29 @@ Yo from a shell script!
|
|||||||
Hello from ruby!
|
Hello from ruby!
|
||||||
```
|
```
|
||||||
|
|
||||||
|
=== Safer Bash Shebang Recipes
|
||||||
|
|
||||||
|
If you're writing a Bash shebang recipe, consider adding `set -euxo pipefail`:
|
||||||
|
|
||||||
|
```make
|
||||||
|
foo:
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euxo pipefail
|
||||||
|
hello='Yo'
|
||||||
|
echo "$hello from Bash!"
|
||||||
|
```
|
||||||
|
|
||||||
|
It isn't strictly necessary, but `set -euxo pipefail` turns on a few useful
|
||||||
|
features that make Bash shebang recipes behave more like normal, linewise Just
|
||||||
|
recipe:
|
||||||
|
|
||||||
|
- `set -e` makes bash exit if a command fails.
|
||||||
|
- `set -u` makes bash exit if a variable is undefined.
|
||||||
|
- `set -x` makes bash print each script line before it's run.
|
||||||
|
- `set -o pipefail` makes bash exit if a command in a pipeline fails.
|
||||||
|
|
||||||
|
Together, these avoid a lot of shell scripting gotchas.
|
||||||
|
|
||||||
==== Shebang Recipe Execution on Windows
|
==== Shebang Recipe Execution on Windows
|
||||||
|
|
||||||
On Windows, shebang interpreter paths containing a `/` are translated from Unix-style
|
On Windows, shebang interpreter paths containing a `/` are translated from Unix-style
|
||||||
@ -845,6 +868,40 @@ The interpreter path `/bin/sh` will be translated to a Windows-style path using
|
|||||||
|
|
||||||
If the interpreter path does not contain a `/` it will be executed without being translated. This is useful if `cygpath` is not available, or you wish to use a Windows style path to the interpreter.
|
If the interpreter path does not contain a `/` it will be executed without being translated. This is useful if `cygpath` is not available, or you wish to use a Windows style path to the interpreter.
|
||||||
|
|
||||||
|
=== Setting Variables in a Recipe
|
||||||
|
|
||||||
|
Recipe lines are interpreted by the shell, not Just, so it's not possible to set
|
||||||
|
Just variables in the middle of a recipe:
|
||||||
|
|
||||||
|
```
|
||||||
|
foo:
|
||||||
|
x := "hello" # This doesn't work!
|
||||||
|
echo {{x}}
|
||||||
|
```
|
||||||
|
|
||||||
|
It is possible to use shell variables, but there's another problem. Every
|
||||||
|
recipe line is run by a new shell instance, so variables set in one line won't
|
||||||
|
be set in the next:
|
||||||
|
|
||||||
|
```make
|
||||||
|
foo:
|
||||||
|
x=hello && echo $x # This works!
|
||||||
|
y=bye
|
||||||
|
echo $y # This doesn't, `y` is undefined here!
|
||||||
|
```
|
||||||
|
|
||||||
|
The best way to work around this is to use a shebang recipe. Shebang recipe
|
||||||
|
bodies are extracted and run as scripts, so a single shell instance will run
|
||||||
|
the whole thing:
|
||||||
|
|
||||||
|
```make
|
||||||
|
foo:
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euxo pipefail
|
||||||
|
x=hello
|
||||||
|
echo $x
|
||||||
|
```
|
||||||
|
|
||||||
=== Multi-line Constructs
|
=== Multi-line Constructs
|
||||||
|
|
||||||
Recipes without an initial shebang are evaluated and run line-by-line, which means that multi-line constructs probably won't do what you want.
|
Recipes without an initial shebang are evaluated and run line-by-line, which means that multi-line constructs probably won't do what you want.
|
||||||
|
Loading…
Reference in New Issue
Block a user