Writing a bash noscript for post-install automatic configurations of a personal system.
Hello!
I'm trying to learn some simple bash noscripting and i made myself a project i'd like to do.
Here's the initial step: https://github.com/Veprovina/CarchyOS/blob/main/Carchyos.sh
It's a noscript that makes a minimal Arch linux into CachyOS hybrid with CachyOS repositories, kernel, and adds configurations specific to my system automatically so i don't have to do it. The goal much later would be to expand it to work on other OS, but this is as far as i've gotten now.
I did test it in a VM, and it works, but it's pretty basic or possibly wrong? I dont know what i'm doing. I didn't ask AI, nor do i want to, so i'm asking here if people can point me to the right direction so i can learn how to achieve all the things i wrote in the "to do" part, and to better understand how the ones i wrote already work.
For instance, i copied the "cat" part from a forum and modified it for my purposes, but idk why it does what it does. I know >> is append to file and > is new file (or rewrite existing file entirely), so maybe there's a more elegant solution to add new lines to an existing file, or write a new file that i just haven't found by googling. Or maybe printf is better than echo for some reason?
Like, i understand what the noscript does, but i might need some deeper understanding to add other stuff.
So far the noscript does:
\- echo every change about to happen in a colored line
\- copies and executes the cachyos noscript that changes the repositories and packages from arch to cacyhos
\- installs pacman packages
\- makes new directories for mount points, adds UUIDs of drives into fstab, then mounts them
\- makes an udev rule for a gamepad
Am i on the correct track or completely off the mark and that's not how it's done? I'd appreciate any insight, and pointing in the right direction, to some good beginner friendly documentation or tutorials so i can learn how to do this myself.
My end goal would be complete and automatic initial setup of the minimal system with one noscript.
https://redd.it/1ohusql
@r_bash
Hello!
I'm trying to learn some simple bash noscripting and i made myself a project i'd like to do.
Here's the initial step: https://github.com/Veprovina/CarchyOS/blob/main/Carchyos.sh
It's a noscript that makes a minimal Arch linux into CachyOS hybrid with CachyOS repositories, kernel, and adds configurations specific to my system automatically so i don't have to do it. The goal much later would be to expand it to work on other OS, but this is as far as i've gotten now.
I did test it in a VM, and it works, but it's pretty basic or possibly wrong? I dont know what i'm doing. I didn't ask AI, nor do i want to, so i'm asking here if people can point me to the right direction so i can learn how to achieve all the things i wrote in the "to do" part, and to better understand how the ones i wrote already work.
For instance, i copied the "cat" part from a forum and modified it for my purposes, but idk why it does what it does. I know >> is append to file and > is new file (or rewrite existing file entirely), so maybe there's a more elegant solution to add new lines to an existing file, or write a new file that i just haven't found by googling. Or maybe printf is better than echo for some reason?
Like, i understand what the noscript does, but i might need some deeper understanding to add other stuff.
So far the noscript does:
\- echo every change about to happen in a colored line
\- copies and executes the cachyos noscript that changes the repositories and packages from arch to cacyhos
\- installs pacman packages
\- makes new directories for mount points, adds UUIDs of drives into fstab, then mounts them
\- makes an udev rule for a gamepad
Am i on the correct track or completely off the mark and that's not how it's done? I'd appreciate any insight, and pointing in the right direction, to some good beginner friendly documentation or tutorials so i can learn how to do this myself.
My end goal would be complete and automatic initial setup of the minimal system with one noscript.
https://redd.it/1ohusql
@r_bash
GitHub
CarchyOS/Carchyos.sh at main · Veprovina/CarchyOS
Scripts to add CachyOS kernel and repositories into a minimal Arch installation. For personal and testing purposes. - Veprovina/CarchyOS
I started a small blog documenting lessons learned, and the first major post is on building reusable, modular Bash libraries (using functions, namespaces, and local)
I've started a new developer log to document lessons learned while working on my book (Bash: The Developer's Approach). The idea is to share the real-world path of an engineer trying to build robust software.
My latest post dives into modular Bash design.
We all know the pain of big, brittle utility noscripts. I break down how applying simple engineering concepts—like Single Responsibility and Encapsulation (via
Full breakdown here: https://www.lost-in-it.com/posts/designing-modular-bash-functions-namespaces-library-patterns/
It's small, but hopefully useful for anyone dealing with noscripting debt. Feedback and critiques are welcome.
https://redd.it/1oj3i2f
@r_bash
I've started a new developer log to document lessons learned while working on my book (Bash: The Developer's Approach). The idea is to share the real-world path of an engineer trying to build robust software.
My latest post dives into modular Bash design.
We all know the pain of big, brittle utility noscripts. I break down how applying simple engineering concepts—like Single Responsibility and Encapsulation (via
local)—can transform Bash into a maintainable language. It's about designing clear functions and building reusable libraries instead of long, monolithic noscripts.Full breakdown here: https://www.lost-in-it.com/posts/designing-modular-bash-functions-namespaces-library-patterns/
It's small, but hopefully useful for anyone dealing with noscripting debt. Feedback and critiques are welcome.
https://redd.it/1oj3i2f
@r_bash
Lost in IT | Kromg
Designing Modular Bash: Functions, Namespaces, and Library Patterns
Learn how to structure Bash code that scales with small functions, namespaces, and library patterns. Discover professional techniques for building reusable Bash libraries.
I want to put totp in my bash noscript
hey so as my noscript say i want to put totp in my noscript,
I am currently working on a project related to get access in servers so i want to use totp in bash which is allowing the user into server , currently i am sharing ssh key over telegram bot which is allowing the user into server but i want to replace it with totp.
Is there is any way i can put like on google authentictor , is google provide api for it ? if not os there is any tool for it ? and how to connect with any app to obtain otp and i will put the otp into the telegram which send it to my noscript in the server and will allow access
https://redd.it/1oj8ala
@r_bash
hey so as my noscript say i want to put totp in my noscript,
I am currently working on a project related to get access in servers so i want to use totp in bash which is allowing the user into server , currently i am sharing ssh key over telegram bot which is allowing the user into server but i want to replace it with totp.
Is there is any way i can put like on google authentictor , is google provide api for it ? if not os there is any tool for it ? and how to connect with any app to obtain otp and i will put the otp into the telegram which send it to my noscript in the server and will allow access
https://redd.it/1oj8ala
@r_bash
Reddit
From the bash community on Reddit
Explore this post and more from the bash community
How to substitute a string in a file
I have a file called test.txt that looks like this
```
gobbledygook
something unique I can key on ['test1', 'test2', 'test3'];
gobbledygook
```
My noscript looks like
```
substitute_string="'test1', 'test2'"
sed -E "s/something unique I can key on\[(.*)\];/${substitute_string}/g" < test.txt > test2.txt
```
I want test2.txt to look like
```
gobbledygook
something unique I can key on ['test1', 'test2'];
gobbledygook
```
but as you probably know, I get this instead:
```
gobbledygook
'test1', 'test2'
gobbledygook
```
If I put \1 in front of the variable, it renders like
```
gobbledygook
'test1', 'test2', 'test3''test1', 'test2'
gobbledygook
```
I am not sure how to replace what's between the brackets, i.e. my first grouping, with my subtitute_string. Can you help?
https://redd.it/1ol6f4n
@r_bash
I have a file called test.txt that looks like this
```
gobbledygook
something unique I can key on ['test1', 'test2', 'test3'];
gobbledygook
```
My noscript looks like
```
substitute_string="'test1', 'test2'"
sed -E "s/something unique I can key on\[(.*)\];/${substitute_string}/g" < test.txt > test2.txt
```
I want test2.txt to look like
```
gobbledygook
something unique I can key on ['test1', 'test2'];
gobbledygook
```
but as you probably know, I get this instead:
```
gobbledygook
'test1', 'test2'
gobbledygook
```
If I put \1 in front of the variable, it renders like
```
gobbledygook
'test1', 'test2', 'test3''test1', 'test2'
gobbledygook
```
I am not sure how to replace what's between the brackets, i.e. my first grouping, with my subtitute_string. Can you help?
https://redd.it/1ol6f4n
@r_bash
Reddit
From the bash community on Reddit
Explore this post and more from the bash community
wanna start noscripting
Hello, i have been using linux for some time now (about 2-3 years)
i have done some easy noscripts for like i3blocks to ask for something like cpu temp
but i have moved to hyprland and i want to get into much bigger noscripts so i want to know what are commands i should know / practise with
or even some commands a normal user won't use like it was for me the awk command or the read command
https://redd.it/1omqxf4
@r_bash
Hello, i have been using linux for some time now (about 2-3 years)
i have done some easy noscripts for like i3blocks to ask for something like cpu temp
but i have moved to hyprland and i want to get into much bigger noscripts so i want to know what are commands i should know / practise with
or even some commands a normal user won't use like it was for me the awk command or the read command
https://redd.it/1omqxf4
@r_bash
Reddit
From the bash community on Reddit
Explore this post and more from the bash community
topalias 3.0.0 has been released
Installation:
Running the topalias utility:
Changes:
Supported Ubuntu 25.10/Python 3.13, Kubuntu 22.04/Python 3.10, KDE neon Rolling
Please test with the latest version of Python 3.15 in KDE neon.
https://redd.it/1on0cjj
@r_bash
Installation:
install -U --upgrade topalias
pipx install --force topalias
python3 -m pip install -U --upgrade topalias
python3.10 -m pip install -U --upgrade topalias
Running the topalias utility:
python3 -m topalias
python3.10 -m pip topalias
python3 topalias/cli.py
Changes:
Supported Ubuntu 25.10/Python 3.13, Kubuntu 22.04/Python 3.10, KDE neon Rolling
Please test with the latest version of Python 3.15 in KDE neon.
https://redd.it/1on0cjj
@r_bash
Reddit
From the bash community on Reddit
Explore this post and more from the bash community
Thoughts on this bash toolkit for VPS (free OS MIT)
(not sure if this is ok to post here?)
Hi all, a decent while ago i started getting into VPS and self hosting and wanted to learn all the ins and outs.
I thought, why not learn command line and Linux for hosting by creating noscripts using bash hehe oh was i in for a ride.
Ive learned a damn lot, and just wanted to share my learning experience. (I kinda went overboard on how i share it lol, lets just say i had a lot of fun evenings)
I basically made a toolkit, that has the concepts, and best practices i learned, and its in a nice looking TUI now. I like how its so powerful without any real depencies. You can do so much!! Unbelievable
I would love some feedback and opinions on it of you who know lots more about bash than I do so i can learn!!
Its free and open source under MIT:
https://github.com/kelvincdeen/kcstudio-launchpad-toolkit
(Yes i used ai to help me. But i understand and know what all critical parts do because thats important to me). And yes i know the noscripts are gigantic, its all build on focused functions and makes it easier for me to see the big picture.
Would love your opinions on it, the good and the critique so i can do better next time
https://redd.it/1onrlcg
@r_bash
(not sure if this is ok to post here?)
Hi all, a decent while ago i started getting into VPS and self hosting and wanted to learn all the ins and outs.
I thought, why not learn command line and Linux for hosting by creating noscripts using bash hehe oh was i in for a ride.
Ive learned a damn lot, and just wanted to share my learning experience. (I kinda went overboard on how i share it lol, lets just say i had a lot of fun evenings)
I basically made a toolkit, that has the concepts, and best practices i learned, and its in a nice looking TUI now. I like how its so powerful without any real depencies. You can do so much!! Unbelievable
I would love some feedback and opinions on it of you who know lots more about bash than I do so i can learn!!
Its free and open source under MIT:
https://github.com/kelvincdeen/kcstudio-launchpad-toolkit
(Yes i used ai to help me. But i understand and know what all critical parts do because thats important to me). And yes i know the noscripts are gigantic, its all build on focused functions and makes it easier for me to see the big picture.
Would love your opinions on it, the good and the critique so i can do better next time
https://redd.it/1onrlcg
@r_bash
GitHub
GitHub - kelvincdeen/kcstudio-launchpad-toolkit: 🚀 KCStudio Launchpad is a command-line TUI for your VPS. It's a non-containerized…
🚀 KCStudio Launchpad is a command-line TUI for your VPS. It's a non-containerized, opinionated deployment and management system for solo developers who want to turn a single server into a s...
Over the Wire - Level 13 to 14
It feels like moving from Level 13 to 14 is a huge step up..I know keys from PGP etc, but I am wondering why the private key from one user should work to log in to the account of another user..
Sure, this level is set up to teach this stuff, but am I correct thinking that the private key is per user of a machine, and not for the entire computer, so this level represents a very unlikely scenario?
Why should I be able to download the private key from User 13 to log into the machine as User 14, in a real-world scenario - or am I missing something?
Here is the solution to get to Level 14 - you log into Bandit13, find the private key, log out, download the key because you know where it is and have the password, and then use the private key from bandit13 to log into bandit14..
(For example https://mayadevbe.me/posts/overthewire/bandit/level14/)
https://redd.it/1oowe8m
@r_bash
It feels like moving from Level 13 to 14 is a huge step up..I know keys from PGP etc, but I am wondering why the private key from one user should work to log in to the account of another user..
Sure, this level is set up to teach this stuff, but am I correct thinking that the private key is per user of a machine, and not for the entire computer, so this level represents a very unlikely scenario?
Why should I be able to download the private key from User 13 to log into the machine as User 14, in a real-world scenario - or am I missing something?
Here is the solution to get to Level 14 - you log into Bandit13, find the private key, log out, download the key because you know where it is and have the password, and then use the private key from bandit13 to log into bandit14..
(For example https://mayadevbe.me/posts/overthewire/bandit/level14/)
https://redd.it/1oowe8m
@r_bash
MayADevBe Blog
OverTheWire Bandit Level 13 -> 14 - Walkthrough
A walkthrough of Level 13 -> 14 of the Bandit wargame from OverTheWire. - SSH Login with key and transferring files from a remote host.
Stuck with a noscript
I'm working on a noscript to (in theory) speed up creating new posts for my hugo website. Part of the noscript runs
But, when I run
Is it possible to quit the hugo server and return to the bash noscript?
The relevant part of the noscript is here:
Thanks!
https://redd.it/1op9g11
@r_bash
I'm working on a noscript to (in theory) speed up creating new posts for my hugo website. Part of the noscript runs
hugo serve so that I can preview changes to my site. I had the intention of checking the site in Firefox, then returning to the shell to resume the noscript, run hugo and then rsync the changes to the server. But, when I run
hugo serve in the noscript, hugo takes over the terminal. When I quit hugo serve with ctrl C, the bash noscript also ends. Is it possible to quit the hugo server and return to the bash noscript?
The relevant part of the noscript is here:
echo "Move to next step [Y] or exit [q]?"read -r editing_finishedif [ $editing_finished = q ]; thenexitelif [ $editing_finished = Y ]; then# Step 6 Run hugo serve# Change to root hugo directory, this should be three levels highercd ../../../# Run hugo local server and display in firefoxhugo serve & firefox `http://localhost:1313/`fiThanks!
https://redd.it/1op9g11
@r_bash
Reddit
From the bash community on Reddit
Explore this post and more from the bash community
Making my first noscript give it a run through I got a few questions
I am looking to make a noscript with categorical response from echo, such as like this from the nano terminal.
Echo " welcome to the program1 program!"
Sleep 2
Clear
Echo " please make a selection from one of these categories!"
Echo "
Story
Todolist
Calendar "
I don't know if I should put a "fi" here or not to keep it from going back to original terminal or leaving the noscript, then want "story" to open a page of text, how can I go about these things, getting functions working clean as it keeps coming out as slop with error syntax or straight up not functioning?
I went into the .bathroom and attempted to make an export function process that ALSO don't work, I have the wrost luck with Linux and bash over the years in the process of learning it I swear, any help please?!?!
https://redd.it/1ophe31
@r_bash
I am looking to make a noscript with categorical response from echo, such as like this from the nano terminal.
Echo " welcome to the program1 program!"
Sleep 2
Clear
Echo " please make a selection from one of these categories!"
Echo "
Story
Todolist
Calendar "
I don't know if I should put a "fi" here or not to keep it from going back to original terminal or leaving the noscript, then want "story" to open a page of text, how can I go about these things, getting functions working clean as it keeps coming out as slop with error syntax or straight up not functioning?
I went into the .bathroom and attempted to make an export function process that ALSO don't work, I have the wrost luck with Linux and bash over the years in the process of learning it I swear, any help please?!?!
https://redd.it/1ophe31
@r_bash
Reddit
From the bash community on Reddit
Explore this post and more from the bash community
3D Graphics Generated & Rendered on the Terminal with just Bash
https://www.youtube.com/watch?v=lU5s11MR5n0
https://redd.it/1ophj34
@r_bash
https://www.youtube.com/watch?v=lU5s11MR5n0
https://redd.it/1ophj34
@r_bash
YouTube
This 3D Engine Runs in Bash. Creating & Rendering a 3D scene on the terminal with 0 external tools.
Source code here! http://github.com/Ponali/bash-bmp
Support me on https://patreon.com/YouSuckatProgramming
- $ whoami
Yo what's up everyone my name's dave and you suck at programming! Connect with me on my socials below and if you're reading this you're…
Support me on https://patreon.com/YouSuckatProgramming
- $ whoami
Yo what's up everyone my name's dave and you suck at programming! Connect with me on my socials below and if you're reading this you're…
config files: .zshenv equivalent?
Hi everyone, I'm a Zsh user looking into Bash and have a question about the user config files. The Zsh startup and exit sequence is quite simple (assuming not invoked with options that disable reading these files):
1. For any shell: Read
2. Is it a login shell? Read
3. Is it an interactive shell? Read
4. Is it a login shell? Read
5. Is it a login shell? Read
Bash is a little different. It has, in this order, as far as I can tell:
1.
2.
3.
Therefore, points 1 + 3 and point 2 are mutually exclusive. Please do highlight any mistakes in this if there are ones.
My question is now how to make this consistent with how Zsh works. One part seems easy: Source
TLDR: What is the correct way to mimic
https://redd.it/1opkvxu
@r_bash
Hi everyone, I'm a Zsh user looking into Bash and have a question about the user config files. The Zsh startup and exit sequence is quite simple (assuming not invoked with options that disable reading these files):
1. For any shell: Read
.zshenv2. Is it a login shell? Read
.zprofile3. Is it an interactive shell? Read
.zshrc4. Is it a login shell? Read
.zlogin (.zprofile alternative for people who prefer this order)5. Is it a login shell? Read
.zlogout (on exit, obviously)Bash is a little different. It has, in this order, as far as I can tell:
1.
.bash_profile (and two substitutes), which is loaded for all login shells2.
.bashrc, which only gets read for interactive non-login shells3.
.bash_logout gets read in all login shells on exit.Therefore, points 1 + 3 and point 2 are mutually exclusive. Please do highlight any mistakes in this if there are ones.
My question is now how to make this consistent with how Zsh works. One part seems easy: Source
.bashrc from .bash_profile if the shell is interactive, giving the unconditional split between "login stuff" and "interactive stuff" into two files that Zsh has. But what about non-interactive, non-login shells? If I run $ zsh some_noscript.zsh, only .zshenv is read and guarantees that certain environment variables like GOPATH and my PATH get set. Bash does not seem to have this, it seems to rely on itself being or there being a login shell to inherit from. Where should my environment variables go if I want to ensure a consistent environment when invoking Bash for noscripts?TLDR: What is the correct way to mimic
.zshenv in Bash?https://redd.it/1opkvxu
@r_bash
Reddit
From the bash community on Reddit
Explore this post and more from the bash community
how to run a foreground command from a background noscript?
im trying to make a 'screensaver' noscript that runs cBonsai upon a certain idle timeout. it works so far, but in the foreground - where i cant execute any commands because the noscript is running.
im running it in the background, but now cBonsai also runs in the background.
so how can i run an explicitly foreground command from background process?
so far ive looked at job control, but it looks like im only getting the PID of the noscript im running, not the PID of the command im executing.
https://redd.it/1ops7rw
@r_bash
im trying to make a 'screensaver' noscript that runs cBonsai upon a certain idle timeout. it works so far, but in the foreground - where i cant execute any commands because the noscript is running.
im running it in the background, but now cBonsai also runs in the background.
so how can i run an explicitly foreground command from background process?
so far ive looked at job control, but it looks like im only getting the PID of the noscript im running, not the PID of the command im executing.
https://redd.it/1ops7rw
@r_bash
Reddit
From the bash community on Reddit
Explore this post and more from the bash community
Simple shell noscript that automates tasks like building github projects, kernels, applications etc. by creating rootless podman containers displayed in tmux and logged with neovim.
https://redd.it/1opwkqd
@r_bash
https://redd.it/1opwkqd
@r_bash
Reddit
From the bash community on Reddit: Simple shell noscript that automates tasks like building github projects, kernels, applications…
Explore this post and more from the bash community
Does my bash noscript scream C# dev?
I was told that this noscript looks very C-sharp-ish. I dont know what that means, beside the possible visual similarity of (beautiful) pascal case.
Do you think it is bad?
https://redd.it/1oq02fy
@r_bash
#!/usr/bin/env bash
# vim: fen fdm=marker sw=2 ts=2
set -euo pipefail
# ┌────┐
# │VARS│
# └────┘
_ORIGINAL_DIR=$(pwd)
_SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
_LOGDIR="/tmp/linstall_logs"
_WORKDIR="/tmp/linstor-build"
mkdir -p "$_LOGDIR" "$_WORKDIR"
# ┌────────────┐
# │INSTALL DEPS│
# └────────────┘
packages=(
drbd-utils
autoconf
automake
libtool
pkg-config
git
build-essential
python3
ocaml
ocaml-findlib
libpcre3-dev
zlib1g-dev
libsqlite3-dev
dkms
linux-headers-"$(uname -r)"
flex
bison
libssl-dev
po4a
asciidoctor
make
gcc
xsltproc
docbook-xsl
docbook-xml
resource-agents
)
InstallDeps() {
sudo apt update
for p in "${packages[@]}" ; do
sudo apt install -y "$p"
echo "Installing $p" >> "$_LOGDIR"/$0-deps.log
done
}
ValidateDeps() {
for p in "${packages[@]}"; do
if dpkg -l | grep -q "^ii $p"; then
echo "$p installed" >> "$_LOGDIR"/$0-pkg.log
else
echo "$p NOT installed" >> "$_LOGDIR"/$0-fail.log
fi
done
}
# ┌─────┐
# │BUILD│
# └─────┘
CloneCL() {
cd $_WORKDIR
git clone https://github.com/coccinelle/coccinelle.git
echo "cloning to $_WORKDIR - noscript running from $_SCRIPT_DIR with original path at $_ORIGINAL_DIR" >> $_LOGDIR/$0-${FUNCNAME[0]}.log
}
BuildCL() {
cd $_WORKDIR/coccinelle
sleep 0.2
./autogen
sleep 0.2
./configure
sleep 0.2
make -j $(nproc)
sleep 0.2
make install
}
CloneDRBD() {
cd $_WORKDIR
git clone --recursive https://github.com/LINBIT/drbd.git
echo "cloning to $_WORKDIR - noscript running from $_SCRIPT_DIR with original path at $_ORIGINAL_DIR" >> $_LOGDIR/$0-${FUNCNAME[0]}.log
}
BuildDRBD() {
cd $_WORKDIR/drbd
sleep 0.2
git checkout drbd-9.2.15
sleep 0.2
make clean
sleep 0.2
make -j $(nproc) KDIR=/lib/modules/$(uname -r)/build
sleep 0.2
make install KBUILD_SIGN_PIN=
}
RunModProbe() {
modprobe -r drbd
sleep 0.2
depmod -a
sleep 0.2
modprobe drbd
sleep 0.2
modprobe handshake
sleep 0.2
modprobe drbd_transport_tcp
}
CloneDRBDUtils() {
cd $_WORKDIR
git clone https://github.com/LINBIT/drbd-utils.git
echo "cloning to $_WORKDIR - noscript running from $_SCRIPT_DIR with original path at $_ORIGINAL_DIR" >> $_LOGDIR/$0-${FUNCNAME[0]}.log
}
BuildDRBDUtils() {
cd $_WORKDIR/drbd-utils
./autogen.sh
sleep 0.2
./configure --prefix=/usr --localstatedir=/var --sysconfdir=/etc
sleep 0.2
make -j $(nproc)
sleep 0.2
make install
}
Main() {
InstallDeps
sleep 0.1
ValidateDeps
sleep 0.1
CloneCL
sleep 0.1
BuildCL
sleep 0.1
CloneDRBD
sleep 0.1
BuildDRBD
sleep 0.1
CloneDRBDUtils
sleep 0.1
BuildDRBDUtils
sleep 0.1
}
# "$@"
Main
I was told that this noscript looks very C-sharp-ish. I dont know what that means, beside the possible visual similarity of (beautiful) pascal case.
Do you think it is bad?
https://redd.it/1oq02fy
@r_bash
Reddit
From the bash community on Reddit
Explore this post and more from the bash community
Grepping logs remains terrible
https://chronicles.mad-scientist.club/tales/grepping-logs-remains-terrible/
https://redd.it/1oqeuud
@r_bash
https://chronicles.mad-scientist.club/tales/grepping-logs-remains-terrible/
https://redd.it/1oqeuud
@r_bash
chronicles.mad-scientist.club
Books. Statues, innoscriptions, memori- al stones.
"Explain what?" "This." He indicated the gardens, the huge imposture was undertaken.
What’s your go-to programming language for noscripting in Linux?
Curious what everyone uses for small automation tasks or system noscripts on Linux.
I used to write all my noscripts in Bash, but I’ve recently started migrating some stuff to Python for better readability and error handling.
Do you stick with Bash, or use something else like Perl, Ruby, or even Go?
https://redd.it/1oqw06f
@r_bash
Curious what everyone uses for small automation tasks or system noscripts on Linux.
I used to write all my noscripts in Bash, but I’ve recently started migrating some stuff to Python for better readability and error handling.
Do you stick with Bash, or use something else like Perl, Ruby, or even Go?
https://redd.it/1oqw06f
@r_bash
Reddit
From the bash community on Reddit
Explore this post and more from the bash community
Interrupts: The Only Reliable Error Handling in Bash
I claim that process group interrupts are the only reliable method for stopping bash noscript execution on errors without manually checking return codes after every command invocation.
**I welcome counterexamples** showing an alternative approach that provides reliable error propagation while meeting both constraints:
- No manual return code checking after each command
- No interrupt-based mechanisms
### What am I claiming?
I am claiming that using interrupts is the only reliable way to stop on errors in bash WITHOUT having to check return codes of each command that you are calling.
### Why do I want to avoid checking return codes of each command?
It is **error prone** as its fairly easy to forget to check a return code of a command. Moving the burden of error checking onto the client instead of the function writer having a way to stop the execution if there is an issue discovered.
And adds noise to the code having to perform, something like
```bash
if ! someFunc; then
echo "..."
return 1
fi
someFunc || {
echo "..."
return 1
}
```
### What do I mean by interrupt?
I mean using an interrupt that will halt the entire process group `kill -INT 0`, `kill -INT -$$` with wire up functions like below:
```bash
interrupt (){
echo.log.yellow "FunctionChain: $(function_chain)";
echo.log.yellow "PWD: [$PWD]";
echo.log.yellow "PID : [$$]";
echo.log.yellow "BASHPID: [$BASHPID]";
interrupt_quietly
}
interrupt_quietly(){
if [[ "${__NO_INTERRUPT__EXIT_ONLY:?}" == "${TRUE:?}" ]]; then
echo.log "Exiting without interrupting the parent process. (__NO_INTERRUPT__EXIT_ONLY=${__NO_INTERRUPT__EXIT_ONLY})";
else
kill -INT 0
kill -INT -$$;
echo.red "Interrupting failed. We will now 'exit 1' as best best effort to stop execution." 1>&2;
fi;
exit "${__NO_INTERRUPT__EXIT_ONLY__EXIT_CODE:?}"
}
```
Such `kill -INT 0`, `kill -INT -$$` usage allows a function that is deep in the call stack to STOP the processing when it detects there has been an issue.
### Why not just use "bash strict mode"?
One of the reasons is that `set -eEuo pipefail` is not so strict and can be very easily accidentally bypassed, just by a check somewhere up the chain whether function has been successful.
```bash
#!/usr/bin/env bash
set -eEuo pipefail
foo() {
echo "foo: i fail"
return 1
}
bar() {
foo
}
main() {
if bar; then
echo "bar was success"
fi
echo "Main finished."
}
main "${@}"
```
Output will be
```txt
foo: i fail
Main finished.
```
Showing us that strict mode did not catch the issue with `foo`.
### Interrupt works reliably:
#### Interrupt works reliably: With simple example where bash strict mode failed
```bash
#!/usr/bin/env bash
foo() {
echo "foo: i fail"
interrupt "FOO FAILED"
}
bar() {
foo
}
main() {
if bar; then
echo "bar was success"
fi
echo "Main finished."
}
main "${@}"
```
Output:
```txt
foo: i fail
Interrupting: [FOO FAILED]
FunctionChain: [main:19 (scratch2.sh)-->main:13 (scratch2.sh)-->bar:9 (scratch2.sh)-->foo:5 (scratch2.sh)-->interrupt]
PWD: [/usr/local/workplace/thorg-root/dendron_notes_external/thorg-vault-external]
PID : [2787322]
BASHPID: [2787322]
```
#### Interrupt works reliably: With subprocesses
```bash
#!/usr/bin/env bash
foo() {
echo "foo: i fail"
interrupt "FOO FAILED"
}
bar() {
foo
}
main() {
bar_res=$(bar)
echo "Main finished."
}
main "${@}"
```
Output:
```txt
FunctionChain: [main:17 (scratch2.sh)-->main:13 (scratch2.sh)-->bar:9 (scratch2.sh)-->foo:5 (scratch2.sh)-->interrupt]
PWD: [/Users/nkondrat/vintrin-env]
PID : [2788193]
BASHPID: [2788195]
```
#### Interrupt works reliably: With pipes
```bash
#!/usr/bin/env bash
foo() {
local input
input="$(cat)"
echo "foo: i fail"
interrupt "FOO FAILED"
}
bar() {
foo
}
main() {
echo hi | bar | grep "hi"
echo "Main finished."
}
main "${@}"
```
Output
```txt
Interrupting: [FOO FAILED]
FunctionChain: [main:19
I claim that process group interrupts are the only reliable method for stopping bash noscript execution on errors without manually checking return codes after every command invocation.
**I welcome counterexamples** showing an alternative approach that provides reliable error propagation while meeting both constraints:
- No manual return code checking after each command
- No interrupt-based mechanisms
### What am I claiming?
I am claiming that using interrupts is the only reliable way to stop on errors in bash WITHOUT having to check return codes of each command that you are calling.
### Why do I want to avoid checking return codes of each command?
It is **error prone** as its fairly easy to forget to check a return code of a command. Moving the burden of error checking onto the client instead of the function writer having a way to stop the execution if there is an issue discovered.
And adds noise to the code having to perform, something like
```bash
if ! someFunc; then
echo "..."
return 1
fi
someFunc || {
echo "..."
return 1
}
```
### What do I mean by interrupt?
I mean using an interrupt that will halt the entire process group `kill -INT 0`, `kill -INT -$$` with wire up functions like below:
```bash
interrupt (){
echo.log.yellow "FunctionChain: $(function_chain)";
echo.log.yellow "PWD: [$PWD]";
echo.log.yellow "PID : [$$]";
echo.log.yellow "BASHPID: [$BASHPID]";
interrupt_quietly
}
interrupt_quietly(){
if [[ "${__NO_INTERRUPT__EXIT_ONLY:?}" == "${TRUE:?}" ]]; then
echo.log "Exiting without interrupting the parent process. (__NO_INTERRUPT__EXIT_ONLY=${__NO_INTERRUPT__EXIT_ONLY})";
else
kill -INT 0
kill -INT -$$;
echo.red "Interrupting failed. We will now 'exit 1' as best best effort to stop execution." 1>&2;
fi;
exit "${__NO_INTERRUPT__EXIT_ONLY__EXIT_CODE:?}"
}
```
Such `kill -INT 0`, `kill -INT -$$` usage allows a function that is deep in the call stack to STOP the processing when it detects there has been an issue.
### Why not just use "bash strict mode"?
One of the reasons is that `set -eEuo pipefail` is not so strict and can be very easily accidentally bypassed, just by a check somewhere up the chain whether function has been successful.
```bash
#!/usr/bin/env bash
set -eEuo pipefail
foo() {
echo "foo: i fail"
return 1
}
bar() {
foo
}
main() {
if bar; then
echo "bar was success"
fi
echo "Main finished."
}
main "${@}"
```
Output will be
```txt
foo: i fail
Main finished.
```
Showing us that strict mode did not catch the issue with `foo`.
### Interrupt works reliably:
#### Interrupt works reliably: With simple example where bash strict mode failed
```bash
#!/usr/bin/env bash
foo() {
echo "foo: i fail"
interrupt "FOO FAILED"
}
bar() {
foo
}
main() {
if bar; then
echo "bar was success"
fi
echo "Main finished."
}
main "${@}"
```
Output:
```txt
foo: i fail
Interrupting: [FOO FAILED]
FunctionChain: [main:19 (scratch2.sh)-->main:13 (scratch2.sh)-->bar:9 (scratch2.sh)-->foo:5 (scratch2.sh)-->interrupt]
PWD: [/usr/local/workplace/thorg-root/dendron_notes_external/thorg-vault-external]
PID : [2787322]
BASHPID: [2787322]
```
#### Interrupt works reliably: With subprocesses
```bash
#!/usr/bin/env bash
foo() {
echo "foo: i fail"
interrupt "FOO FAILED"
}
bar() {
foo
}
main() {
bar_res=$(bar)
echo "Main finished."
}
main "${@}"
```
Output:
```txt
FunctionChain: [main:17 (scratch2.sh)-->main:13 (scratch2.sh)-->bar:9 (scratch2.sh)-->foo:5 (scratch2.sh)-->interrupt]
PWD: [/Users/nkondrat/vintrin-env]
PID : [2788193]
BASHPID: [2788195]
```
#### Interrupt works reliably: With pipes
```bash
#!/usr/bin/env bash
foo() {
local input
input="$(cat)"
echo "foo: i fail"
interrupt "FOO FAILED"
}
bar() {
foo
}
main() {
echo hi | bar | grep "hi"
echo "Main finished."
}
main "${@}"
```
Output
```txt
Interrupting: [FOO FAILED]
FunctionChain: [main:19
(scratch2.sh)-->main:15 (scratch2.sh)-->bar:11 (scratch2.sh)-->foo:7 (scratch2.sh)-->interrupt]
PWD: [/Users/nkondrat/vintrin-env]
PID : [2788569]
BASHPID: [2788572]
```
#### Interrupts works reliably: when called from another file
```bash
#!/usr/bin/env bash
main() {
echo "main-1 about to call another noscript"
/tmp/scratch3.sh
echo "post-calling another noscript"
}
main "${@}"
```
```bash
#!/usr/bin/env bash
#/tmp/scratch3.sh
main() {
echo "IN another file, about to fail"
interrupt "interrupting from another file"
}
main "${@}"
```
Output:
```txt
main-1 about to call another noscript
IN another file, about to fail
Interrupting: [interrupting from another file]
FunctionChain: [main:10 (scratch3.sh)-->main:7 (scratch3.sh)-->interrupt]
PWD: [/Users/nkondrat/vintrin-env]
PID : [2792454]
BASHPID: [2792454]
```
### In Conclusion: Interrupts Work Reliably Across Cases
Process group interrupts work reliably across all core bash noscript usage patterns.
Process group interrupts work best when running noscripts in the terminal, as interrupting the process group in noscripts running under CI/CD is not advisable, as it can halt your CI/CD runner.
And if you have another reliable way for error propagation in bash that meets
- No manual return code checking after each command
- No interrupt-based mechanisms
Would be great to hear about it!
https://redd.it/1orh24d
@r_bash
PWD: [/Users/nkondrat/vintrin-env]
PID : [2788569]
BASHPID: [2788572]
```
#### Interrupts works reliably: when called from another file
```bash
#!/usr/bin/env bash
main() {
echo "main-1 about to call another noscript"
/tmp/scratch3.sh
echo "post-calling another noscript"
}
main "${@}"
```
```bash
#!/usr/bin/env bash
#/tmp/scratch3.sh
main() {
echo "IN another file, about to fail"
interrupt "interrupting from another file"
}
main "${@}"
```
Output:
```txt
main-1 about to call another noscript
IN another file, about to fail
Interrupting: [interrupting from another file]
FunctionChain: [main:10 (scratch3.sh)-->main:7 (scratch3.sh)-->interrupt]
PWD: [/Users/nkondrat/vintrin-env]
PID : [2792454]
BASHPID: [2792454]
```
### In Conclusion: Interrupts Work Reliably Across Cases
Process group interrupts work reliably across all core bash noscript usage patterns.
Process group interrupts work best when running noscripts in the terminal, as interrupting the process group in noscripts running under CI/CD is not advisable, as it can halt your CI/CD runner.
And if you have another reliable way for error propagation in bash that meets
- No manual return code checking after each command
- No interrupt-based mechanisms
Would be great to hear about it!
https://redd.it/1orh24d
@r_bash
Reddit
From the bash community on Reddit
Explore this post and more from the bash community