Filled by the LAFO script after a successful real provisioning pass.
---
## 3. Why the scripts use Python for CSV parsing
A naive Bash parser such as:
```bash
IFS=, read ...
```
is not robust CSV parsing.
CSV can contain quoted fields and punctuation. The scripts therefore use Python's standard `csv` module and hand the parsed values to Bash as tab-separated fields.
Pattern:
```bash
while IFS=$'\t'read-r full_name username uid gid ssh_public_key date_added;do
...
done < <(
python3 - "$REGISTRY"<<'PY'
...
PY
)
```
Bash performs system administration; Python performs CSV syntax handling.
---
## 4. Bash safety settings
Both scripts use:
```bash
set-euo pipefail
```
### `-e`
Stops on an unhandled command failure.
### `-u`
Stops when an undefined variable is used.
### `pipefail`
A pipeline fails if any command in the pipeline fails.
These settings reduce the chance of silent partial provisioning.
---
## 5. Argument handling and dry-run
Both scripts accept:
```bash
script.sh [--dry-run] registry.csv
```
Argument handling:
```bash
DRY_RUN=false
if[["${1:-}"=="--dry-run"]];then
DRY_RUN=true
shift
fi
REGISTRY="${1:-}"
```
`shift` removes `--dry-run`, leaving the registry path as the first positional argument.
---
## 6. Common validation behavior
Both scripts verify:
- script is run as root;
- registry exists;
- Python 3 exists;
- UID is numeric;
- GID is numeric;
- UID is within the reserved range;
- GID is within the reserved range.
Fatal errors use:
```bash
die(){
echo"ERROR: $*">&2
exit 1
}
```
The core safety rule is:
```text
missing state -> create
correct state -> verify
unexpected state -> stop
```
The scripts deliberately avoid silently repairing unexpected account state.