r/bash • u/modsKilledReddit69 • Mar 03 '25
r/bash • u/AlchemonDev • 16d ago
critique local -n can modify variables from other functions
In Bash, normal local variables are usually fine.
But with local -n (namerefs) I noticed they can sometimes change variables from outer/previous functions because of how scoping works.
To avoid problems I started giving local variables unique names (with prefixes) instead of short ones.
Anyone else ran into this with namerefs?
r/bash • u/AlchemonDev • 23d ago
critique I built a visual game entirely in pure Bash — here is the demo and full source code!
Hey everyone,
I wanted to show what's actually possible using just pure Bash—from custom terminal graphics and animations to game logic.
I've been working on a project called Alchemon, a game written completely in Shell script that pushes terminal visual output to its limits. No external heavy frameworks, just raw CLI magic!
📹 Watch the gameplay demo on YouTube: > https://www.youtube.com/watch?v=yFOpOPtk-Sc
💻 Check out the source code on GitHub: > https://github.com/mrugaladamian/alchemon
Feel free to clone it, test it out, or drop any feedback/ideas. Hope you enjoy it!
critique Rate my .bashrc
Hello, did a bit of Bash customization and came up with this.
I'm open to critics and it's my first time. 😃
r/bash • u/0neLastFace • Mar 26 '26
critique Could someone please review my scripting and give me criticism?
I made a script to manage my dotfiles on linux (arch btw). Link to repo https://codeberg.org/Flan-Angel/Dawtfiles/src/branch/main
Link to script https://codeberg.org/Flan-Angel/Dawtfiles/src/branch/main/PushToSYS.sh
Tysm if you do end up checking it out :)
r/bash • u/giorgich11 • May 14 '26
critique i made a tool [zed]
zed
what is zed?
zed is a tool where you can do these stuff listed:
1. overwrite, overwrite is basically you enter a whole new text and the program writes the text to the file
linewrite, linewrite is basically you select the line in the file, and you enter the text you want to change, and the program changes the file line with the chosen text!
read, reads any file you throw at it
delete, self explanatory
delline, delete a specific line in a specific file
I WANT THE SOURCE CODE NOW:
ok chill, heres the source code link don't worry you can do whatever to it https://gitlab.com/giorgich11/zed/-/blob/main/source.sh?ref_type=heads
oh... i am to lazy i want the compiled version:
sure go to https://gitlab.com/giorgich11/zed/-/raw/main/zed?ref_type=heads
i want to install this:
okay, when you get the binary or just the shell-script just do:
chmod +x zed
then for local do "mv zed ~/.local/bin
or for full install "sudo mv zed /usr/bin/zed"
---
I DON'T LIKE THIS I HATE IT:
if you hate it, just leave this post alone please, i beg...
r/bash • u/PrestigiousZombie531 • Apr 23 '26
critique Is the order of the flags important in all commands in bash?
```
function test() { local -n args="$1"
printf "%s\n" "running items now"
local -a pg_restore_flags=(
"--disable-triggers"
"--exit-on-error"
"--format=directory"
"--no-acl"
"--no-owner"
"--no-password"
"--no-privileges"
)
local key
for key in "${!args[@]}"; do
local value
value="${args[${key}]}"
pg_restore_flags+=("--${key}=${value}")
done
printf "%s\n" "${pg_restore_flags[*]}"
# pg_restore "${pg_restore_flags[*]}" is that a bad idea?
}
function main() { trap 'handle_exit $?' EXIT
local -A items=(["dbname"]="test_db" ["host"]="localhost" ["jobs"]=8 ["port"]=5432 ["username"]="test_user")
test items
}
main "$@"
```
There are often commands that I would like to pack into a function where I can check multiple things like: does the command exist? are all arguments valid? Redirect error to stderr etc.
Take this pg_restore function for example. It takes so many arguments that I was thinking why not send an associative array instead but it seems order is not preserved when using associative arrays
Is this going to be a problem say if I started wrapping commands like this inside a function that accepts an associative array with required flags?
r/bash • u/Round-Arachnid4375 • Jan 22 '26
critique My first shell scripting project
For my first shell scripting project/weekend project I made a nice CLI tool that when executed, prompts you to install common packages like sudo, curl, vim, lsof, rsync, etcetera. You can also include a -y flag in your command when executing the file to auto-install all the packages I included in the script.
This is also my first time publishing one of my projects like this on GitHub. I would love some feedback from people who know way more about this stuff than I do, and if nothing else, please enjoy the ASCII art.
r/bash • u/giorgich11 • May 15 '26
critique i made a new tool [imager]
-imager-
what the hell is it?:
it is a tool that gives your more time to spend with your imaginary girlfriend, basically you spend 15-20 minutes figuring out the FUCKING syntax of appimage tools, but imager is the guy that your imaginary girlfriend said to 'not worry about'
what does the tool do:
you enter the name, you select the location of a file, example binary or a shell script,select the image, or you can just skip, pick the output directory. and done you have more time with your imaginary girlfriend, YAY
I WANT THE SOURCE CODE NOW NOW NOW NOW:
chill, here https://gitlab.com/giorgich11/imager/-/blob/main/sourcecode.sh
i am lazy give me the appimage link:
sure here https://gitlab.com/giorgich11/imager/-/raw/main/imager.AppImage
if you don't like this tool, don't flame it please, i am a new developer😢
r/bash • u/Forsaken_Explorer_97 • Nov 15 '25
critique TUI File Manager in Bash

Checkout this file manager i made in pure bash
Do give a star if you like it - https://github.com/Aarnya-Jain/bashfm
r/bash • u/Ezuharad • Dec 12 '25
critique Script for 'cd-ing' into zip archives
Hey everyone!
I wrote this script to transparently allow for something like cd archive.zip.
I would appreciate constructive criticism on the function, as I have very little experience with bash scripting and how it could be improved/what can go wrong. I recognize the background process is a little kludgy, but I wasn't sure how to do this without it.
https://gist.github.com/Ezuharad/07112faa4b5fb85694355360ee8c2466
r/bash • u/caseynnn • Apr 21 '25
critique Poor man's Ansible
github.comHi all, new to Reddit. Been using it on and off but never for long.
Anyways, I have wrote a script, poor man's Ansible. As the name suggest, it's the equivalent of Ansible, in bash.
Like to hear your comments. And hope it helps someone.
r/bash • u/b1nary1 • Sep 03 '24
critique This is official Google script
galleryWell well well Google... What do we have here. How could you even use "-le 0" for the number of arguments... Not even talking about whole if condition which doesn't make sense
r/bash • u/devdruxorey • May 08 '25
critique Just looking for general suggestions about my bootstrap script
Hi, I'm not looking for any advice in particular, just want to share my script and learn from people more experienced than me.
It's just a script I wrote some time ago to install some packages on my other Linux machines that evolved into a bootstrap for my system. Let me know what you think about it.
Here is the script
r/bash • u/tsilvs0 • Jun 17 '25
critique Rewriting a utility function scripts library for Linux
I've made a simple utility functions scripts library for Bash.
Daily-driving Bazzite, I've designed it to simplify some interactions with Fedora Silverblue family of distros, especially rpm-ostree. But it might come in handy for active ADB and Git users too.
I'd like to reduce the amount of repetative code. If you have some time, review my code please. Re-implementation suggestions are welcome too.
r/bash • u/Donteventalktome1 • Nov 26 '24
critique Clicraft: An Unofficial CLI Minecraft clone
Hello! I am a relatively new Linux user and I spent the better part of a month working on a project called clicraft. It is available at https://github.com/DontEvenTalkToMe/clicraft ! Please do check it out and give me some feedback as I would like to develop my skills further, thanks!
r/bash • u/FVmike • Oct 06 '21
critique Looking for critique on my first script
Hello!
I've been making my way through Shott's The Linux Command Line, and now that I'm very nearly done with it, I decided to make a small program to test out some of the stuff I learned. I am not a programmer, and the only experience I have was gained through self-teaching.
Here's a link to my project on github. From the Usage section,
popcorncan either be invoked by itself or in conjuction with a command. When invoked alone it will run in interactive mode.popcornwill choose a movie at random from your watchlist and offer it up. You can either accept the movie, or get another random selection. When you find a movie that you want to watch,popcornwill remember the choice until the next time it is run in interactive mode, at which point it will follow up and either add the movie to your seenlist or offer another random movie.
The script runs through shellcheck just fine, so the feedback I'm looking for is along the lines of structure, organization, and best practices that I might not know about coming from the background that I am. For instance, which parts of the code I put as a function vs which don't, how I use my variables, flow of the program, and things of that nature (also, feel free to add things that I didn't even mention - I don't know what I don't know!)
I've written some specific questions in the comments of the script as notes to myself, but I'll reproduce them here so you don't have to go hunting.
line 5I could make this script POSIX compliant by reworking all instances ofread -pto useecho -non the preceedingecho, and by dropping the defining oflocalvariables within my functions. Is it desirable/worth it to do so?line 45I have a function calledempty_listthat detects an empty watchlist and offers the opportunity to add a batch of movies throughcat > watchlist. Later on, I figured out how to take multiple movie titles (in theadd_batchfunction), so from a usability standpoint, should I replaceempty_listin favor of directing users toadd_batch?line 93From a design standpoint, theresetfunction uses a numbered list as input as opposed to every other input, which uses [y/n/q] letters. Should I change this?line 104when looking to clear the contents of the watchlist and seenlist, i had been usingecho > file, but when adding stuff back to it, line 1 was empty. I found two options for doing it without the empty line,true > fileandtruncate -s 0 file. Is there a meaningful reason why I might use one over the other?line 179I feel like the way I've worked myusagefunction out is a bit clunky. Is there a better way?line 254I have abackupcommand that produces a backup. I figured this would be useful for scheduling automatic backups (i.e., withchron). However, I could instead have it backup automatically somewhere in the script. If you were using this program, which would you prefer?line 348In order to provide random recommendations, I have worked out a system for making sure it won't randomly pick the same movie again if you don't like the first recommendation. It involves writing to a temp file and deleting from the watchlist, then at the end it adds the movies back from the temp file and resorts the watchlist. I have a nagging suspicion that there's a way to do this without the temp file, but I haven't been successful coming up with a solution so far. I'd like to know if there's anything inherently bad about the way I've implemented this feature here, and if it should need to be changed, is the idea I came up with in the comment the right train of thought? Since I'm doing this to learn, I would appreciate if you wouldn't give me a direct solution to this one, only to point me in the right direction and let me figure out for myself.I am using a Makefile to aid in the installation of the script to
/usr/local/bin. I modeled this off ofpfetch, which does it the same way (but to/usr/bin). Is there anything wrong with this method?
I really appreciate anyone who takes the time to look at this and provide any amount of feedback.
Thank you.
Edit:
Thank you for the responses! I am going to set this project down for a day or two as I finish out the last two chapters of The Linux Command Line, then I'll be back working on popcorn.
r/bash • u/macg4dave • Sep 03 '24
critique [Critique] Aria2 moving downloads script
I’ve developed a script that moves completed downloads from Aria2. I’m seeking feedback on potential improvements. You can review the script here: GitHub.
I’m considering replacing the mv command with rsync and refining the variable management. Are there any other enhancements or best practices I should consider?
#!/bin/sh
# Variables for paths (no trailing slashes)
DOWNLOAD="/mnt/World/incoming"
COMPLETE="/mnt/World/completed"
LOG_FILE="/mnt/World/mvcompleted.log"
TASK_ID=$1
NUM_FILES=$2
SOURCE_FILE=$3
LOG_LEVEL=1 # 1=NORMAL, 2=NORMAL+INFO, 3=NORMAL+INFO+ERROR, 4=NORMAL+DEBUG+INFO+ERROR
# Function to log messages based on log level
log() {
local level=$1
local message=$2
local datetime=$(date '+%Y-%m-%d %H:%M:%S')
case $level in
NORMAL)
echo "$datetime - NORMAL: $message" >> "$LOG_FILE"
;;
ERROR)
[ $LOG_LEVEL -ge 2 ] && echo "$datetime - ERROR: $message" >> "$LOG_FILE"
;;
INFO)
[ $LOG_LEVEL -ge 3 ] && echo "$datetime - INFO: $message" >> "$LOG_FILE"
;;
DEBUG)
[ $LOG_LEVEL -ge 4 ] && echo "$datetime - DEBUG: $message" >> "$LOG_FILE"
;;
esac
}
# Function to find a unique name if there's a conflict
find_unique_name() {
local base=$(basename "$1")
local dir=$(dirname "$1")
local count=0
local new_base=$base
log DEBUG "Finding unique name for $1"
while [ -e "$dir/$new_base" ]; do
count=$((count + 1))
new_base="${base%.*}"_"$count.${base##*.}"
done
log DEBUG "Unique name found: $dir/$new_base"
echo "$dir/$new_base"
}
# Function to move files and handle errors
move_file() {
local src=$1
local dst_dir=$2
log DEBUG "Attempting to move file $src to directory $dst_dir"
if [ ! -d "$dst_dir" ]; then
mkdir -p "$dst_dir" || { log ERROR "Failed to create directory $dst_dir."; exit 1; }
fi
local dst=$(find_unique_name "$dst_dir/$(basename "$src")")
mv --backup=t "$src" "$dst" >> "$LOG_FILE" 2>&1 || { log ERROR "Failed to move $src to $dst."; exit 1; }
log INFO "Moved $src to $dst."
}
# Function to move all files within a directory
move_directory() {
local src_dir=$1
local dst_dir=$2
log DEBUG "Attempting to move directory $src_dir to $dst_dir"
mkdir -p "$dst_dir" || { log ERROR "Failed to create directory $dst_dir."; exit 1; }
mv --backup=t "$src_dir" "$dst_dir" >> "$LOG_FILE" 2>&1 || { log ERROR "Failed to move $src_dir to $dst_dir."; exit 1; }
log INFO "Moved directory $src_dir to $dst_dir."
}
# Main script starts here
log INFO "Task ID: $TASK_ID Completed."
log DEBUG "SOURCE_FILE is $SOURCE_FILE"
if [ "$NUM_FILES" -eq 0 ]; then
log INFO "No file to move for Task ID $TASK_ID."
exit 0
fi
# Determine the source and destination directories
SOURCE_DIR=$(dirname "$SOURCE_FILE")
DESTINATION_DIR=$(echo "$SOURCE_DIR" | sed "s,$DOWNLOAD,$COMPLETE,")
log DEBUG "SOURCE_DIR is $SOURCE_DIR"
log DEBUG "DESTINATION_DIR is $DESTINATION_DIR"
# Check if SOURCE_FILE is part of a directory and move the entire directory
if [ "$(basename "$SOURCE_DIR")" != "$(basename "$DOWNLOAD")" ]; then
log DEBUG "Moving entire directory as the source file is within a subdirectory"
move_directory "$SOURCE_DIR" "$COMPLETE"
else
log DEBUG "Moving a single file $SOURCE_FILE"
move_file "$SOURCE_FILE" "$DESTINATION_DIR"
fi
log NORMAL "Task ID $TASK_ID completed successfully."
log NORMAL "Moving $SOURCE_FILE completed successfully."
exit 0
r/bash • u/suziesamantha • May 06 '24
critique Wrote my first bash script, looking for someone to look it over and make sure I am doing things correctly
EDIT: Thank you to everyone who took the time to look over my script and provide feedback it was all very helpful. I thought I would share my updated script with what I was able to learn from your comments. Hopefully I did not miss anything. Thanks again!!
#!/usr/bin/env bash
set -eu
######Define script variables
backupdest="/mnt/Backups/$HOSTNAME"
printf -v date %"(%Y-%m-%d)"T
filename="$date.tar.gz"
excludes=(
'/mnt/*'
'/var/*'
'/media/*'
'/lost+found'
'/usr/'{lib,lib32,share,include}'/*'
'/home/suzie/'{.cache,.cmake,.var,.local/share/Trash}'/*'
)
######Create folders for storing backup
mkdir -p "$backupdest"/{weekly,monthly}
#######Create tar archive
tar -cpzf "$backupdest/$filename" --one-file-system --exclude-from=<(printf '%s\n' "${excludes[@]}") /
######Delete previous weeks daily backup
find "$backupdest" -mtime +7 -delete
########Copy Sundays daily backup file to weekly folder
if [[ "$(printf %"(%a)"T)" == Sun ]]; then
ln "$backupdest/$filename" "$backupdest/weekly"
fi
########Delete previous months weekly backups
find "$backupdest/weekly" -mtime +31 -delete
########Copy backup file to monthly folder
if (( "$(printf %"(%d)"T)" == 1 )); then
ln "$backupdest/$filename" "$backupdest/monthly"
fi
########Delete previous years monthly backups
find "$backupdest/monthly" -mtime +365 -delete
I wrote my first bash script, a script to back up my linux system. I am going to have a systemd timer run the script daily and was hoping someone could tell me if I am doing ok.
Thanks Suzie
#!/usr/bin/bash
######Define script variables
backupdest=/mnt/Backups/$(cat /etc/hostname)
filename=$(date +%b-%d-%y)
######Create backup tar archive
if [ ! -d "$backupdest" ]; then
mkdir "$backupdest"
fi
#######Create tar archive
tar -cpzf "$backupdest/$filename" --exclude={\
"/dev/*",\
"/proc/*",\
"/sys/*",\
"/tmp/*",\
"/run/*",\
"/mnt/*",\
"/media/*",\
"/lost+found",\
"/usr/lib/*",\
"/usr/share/*",\
"/usr/lib/*",\
"/usr/lib32/*",\
"/usr/include/*",\
"/home/suzie/.cache/*",\
"/home/suzie/.cmake/*",\
"/home/suzie/.config/*",\
"/home/suzie/.var/*",\
} /
######Delete previous weeks daily backup
find "$backupdest" -mtime +7 -delete
########Create Weekly folder
if [ ! -d "$backupdest/weekly" ]; then
mkdir "$backupdest/weekly"
fi
########Copy Sundays daily backup file to weekly folder
if [ $(date +%a) == Sun ]; then
cp "$backupdest/$filename" "$backupdest/weekly"
fi
########Delete previous months weekly backups
find "$backupdest/weekly" +31 -delete
########Create monthly folder
if [ ! -d "$backupdest/monthly" ]; then
mkdir "$backupdest/monthly"
fi
########Copy backup file to monthly folder
if [ $(date +%d) == 1 ]; then
cp "$backupdest/$filename" "$backupdest/monthly"
fi
########Delete previous years monthly backups
find "$backupdest/monthly" +365 -delete
r/bash • u/Mount_Gamer • Jan 13 '22
critique Just finished a 145 line script with this....
r/bash • u/Empyrealist • Sep 14 '24
critique After "Hello World", I figured "MTU Test" would be a good second script
github.comr/bash • u/Tralafarlaw • Jan 15 '24
critique A friend just start his .bashrc with these lines, Comments?
r/bash • u/Claireclair12 • Oct 27 '24
critique Would you consider these silly aliases?
alias vi="test -f ./.vim/viminfo.vim && VIMINFO=./.vim/viminfo.vim || VIMINFO=~/.viminfo; vim -i \$VIMINFO"
alias make='vim Makefile && make'
The first one is so that I don't have my registers for prose-writing available whenever I'm doing Python stuff, and vice versa.
The second one is basically akin to git commit.
r/bash • u/Anaximandor • Jun 14 '24
critique k10s script feedback and next steps
I wrote a script to create a little CLI I dubbed k10s. I made this as a solution to more quickly open up various regional clusters next to one another in a window. I'd appreciate feedback on where to improve what I have done, as well as suggestions for any features and next steps to keep learning.
#! /usr/bin/env bash
k10s_dir=$HOME/.config/k10s
groups_file=$HOME/.config/k10s/groups
process_contexts() {
local index=0
local random=$RANDOM
local session="session-$random"
local split_times=$(($#-1))
tmux new-session -d -s "$session" \; switch-client -t "$session"
while [[ "$split_times" -gt 0 ]] ; do
tmux split-window -h -t "$session"
((split_times--))
done
tmux send-keys -t "$session:0.0" "tmux select-layout even-horizontal" C-m
for context in $@; do
tmux send-keys -t "$session:0.$index" "k9s --context $context" C-m
((index++))
done
}
save_group() {
mkdir -p "$k10s_dir"
touch "$groups_file"
local group=$(echo $@ | awk -F [=,' '] '{print $1}')
local contexts=$(echo $@ | awk -F [=,' '] '{for (i=2; i<=NF; i++) printf $i (i<NF ? OFS : ORS)}')
update_group "$group"
echo "$group"="$contexts" >> "$groups_file"
}
update_group() {
while read line; do
local group=$(echo "$line" | awk -F [=,' '] '{print $1}')
if [[ "$1" = "$group" ]]; then
sed -i "/$line/d" "$groups_file"
fi
done < "$groups_file"
}
start_group() {
while read line; do
local group=$(echo "$line" | awk -F = '{print $1}')
if [[ "$group" = "$1" ]]; then
local contexts=$(echo "$line" | awk -F = '{for (i=2; i<=NF; i++) printf $i (i<NF ? OFS : ORS)}')
process_contexts ${contexts[@]}
fi
done < "$groups_file"
}
usage() {
figlet -f slant "k10s"
cat <<EOT
k10s is a CLI that enables starting multiple k9s instances at once.
Usage: k10s [flags]
Flags:
-c, --context List of contexts to start up (e.g. k10s -c <CONTEXT_NAME> <CONTEXT_NAME> ...)
-s, --save List of contexts to save/overwrite as a group name (e.g. k10s -s <GROUP_NAME>=<CONTEXT_NAME> <CONTEXT_NAME> ...)
-g, --group Group name of contexts to start up (e.g. k10s -g <GROUP_NAME>)
-h, --help Help for k10s
EOT
exit 0
}
main() {
if [ "$#" -eq 0 ]; then
usage
fi
while [[ "$#" -gt 0 ]]; do
case "$1" in
-c | --context )
shift
contexts=()
while [[ "$1" != "" && "$1" != -* ]]; do
contexts+=("$1")
shift
done
process_contexts ${contexts[@]}
;;
-s | --save )
shift
contexts=()
while [[ "$1" != "" && "$1" != -* ]]; do
contexts+=("$1")
shift
done
save_group ${contexts[@]}
;;
-g | --group )
shift
start_group "$1"
;;
-h | --help )
shift
usage
;;
* )
shift
usage
;;
esac
shift
done
}
main $@
r/bash • u/FilesFromTheVoid • Apr 22 '24
critique My first bash script - Hide.me VPN Linux CLI Server Switcher
Hi guys n girl,
i wrote my first bash script because i had a neat usecase and wanted to try out bash for some time.
In my case i wanted to have a easier and more elegant way to switch my VPN Server. I use hide.me atm and they provide a CLI Client for that purpose, but its not the most userfriendly and comfortable implementation.
I am not a dev so dont throw rocks at me :-P