r_bash – Telegram
What the heck did I put in my bashrc?

I put this line in my .bashrc years ago:

bat () { echo "$(<"$@")" ; }

But I have been away from Linux since then. I tried it on my new installation (different distro) and get this error:

bash: "$@": ambiguous redirect

Anybody have any idea what I was thinking then?

https://redd.it/1pl635u
@r_bash
How does ${VARNAME@Q} ACTUALLY work

export SUFFIX="s/Mom/World/" && echo "Hello Mom" | sed ${SUFFIX@Q}

export SUFFIX="s/Mom/World/" && echo "Hello Mom" | sed "${SUFFIX}"

export SUFFIX="s/Mom/World/" && echo "Hello Mom" | sed "$(printf "%q" "$SUFFIX")"

Why does the first of these not work?

sed is receiving the ' characters in the ${SUFFIX@Q} one.

When exactly does it expand? How should I best think about this?

https://redd.it/1plbkq4
@r_bash
Script for 'cd-ing' into zip archives

Hey everyone!

I wrote this noscript 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 noscripting 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.

#!/usr/bin/env zsh
# custom cd command allowing for transparent reading and writing of of zip
# archives.
function cd {
# if fuse-zip is not found, then use builtin cd
if ! command -v fuse-zip &>/dev/null; then
builtin cd "$@";
return "$?";
fi
local TARGET_FILE="$1";
if [[ "$#" == 0 || ! -f "$TARGET_FILE" ]]; then
builtin cd "$@";
return $?;
fi
local TARGET_FILE_EXTENSION="${TARGET_FILE:e}";
if [[ ! "$TARGET_FILE" =~ "apk|docx|epub|jar|pptx|pubx|xlsx|zip" ]]; then
builtin cd "$@";
return $?;
fi
if [[ ! -w "$TARGET_FILE" ]]; then
echo "Insufficient permissions to enter possible archive \"$TARGET_FILE\"" 1>&2;
return 1;
fi
echo "Attempting to enter possible archive \"$TARGET_FILE\"..." 1>&2;
local TARGET_FILE_PATH="$(realpath $TARGET_FILE)";
local FILE_NAME="${TARGET_FILE_PATH:t}";
# create a unique name for the stashed file
local TARGET_FILE_PATH_HASH="$(echo -n $TARGET_FILE_PATH | sha1sum | cut -d' ' -f1)";
# ensure stash exists
local STASH_DIR_PATH="$HOME/.zip_fuse_cache";
local STASH_FILE_PATH="$STASH_DIR_PATH/$TARGET_FILE_PATH_HASH-$FILE_NAME";
# prepare for mount
local MOUNT_POINT="$TARGET_FILE_PATH";
mv "$TARGET_FILE_PATH" "$STASH_FILE_PATH";
mkdir -p "$MOUNT_POINT";
# TODO: support other extensions:
# - tar
# - tar.gz
# - 7z
# - rar
case "$TARGET_FILE_EXTENSION" in
"apk" | "docx" | "epub" | "jar" | "pptx" | "pubx" | "xlsx" | "zip") # a large number of filetypes are actually zip archives in disguise
if ! fuse-zip "$STASH_FILE_PATH" "$MOUNT_POINT"; then
echo "\"$FILE_NAME\" not a valid $TARGET_FILE_EXTENSION file" 1>&2;
rmdir "$MOUNT_POINT";
mv "$STASH_FILE_PATH" "$TARGET_FILE_PATH";
return 1;
fi
builtin cd "$TARGET_FILE_PATH";
;;
*)
echo "Unsupported file type \"$TARGET_FILE_EXTENSION\"" 1>&2;
rmdir "$MOUNT_POINT";
mv "$STASH_FILE_PATH" "$TARGET_FILE_PATH";
return 1;
esac
echo "Stashed $TARGET_FILE at $STASH_FILE_PATH" 1>&2;
# background process to monitor for file closing
echo "Monitoring for unmount at process: " 1>&2;
(
cd "$HOME";
while fuser -m "$MOUNT_POINT" &>/dev/null ; do
sleep 3;
done
fusermount -u "$MOUNT_POINT";
# ensure fuse-zip finishes writing
sleep 1;
while ps aux | grep -q "[f]use-zip.*$STASH_FILE_PATH"; do
sleep 0.5;
done
rmdir "$MOUNT_POINT";
mv "$STASH_FILE_PATH" "$TARGET_FILE_PATH";
exit 0;
) &
disown;
return 0;
}


I also have the following in my zshrc in case the background process is somehow interrupted:
#!/usr/bin/env zsh

# checks the .zip_fuse_cache used by .dotfiles/zsh/.config/zsh/functions/cd for
# orphaned files, and alerts the user of any if found.

if [[ -n "$(ls $HOME/.zip_fuse_cache)" ]]; then
echo "Files detected in $HOME/.zip_fuse_cache." 1>&2;
echo "This indicates possible corruption of archives." 1>&2;
echo "Please check the following files: " 1>&2;
echo "$(ls -A $HOME/.zip_fuse_cache/)";
fi


https://redd.it/1pl6gsb
@r_bash
Recursive file renaming based on parent directory

I have some ripped audiobooks that are currently structured as

/book
/disc 1
/track 1.mp3, track 2.mp3
/disc 2
/track 1.mp3, track 2.mp3

and I need to rename and move the tracks to follow this structure

/book
/disc 01 - track 1.mp3,disc 01 - track 2.mp3, disc 02 - track 1.mp3, disc 02 - track 2.mp3

I know I can use mv to do part of this i.e. for f in *.mp3; do mv "$f" "CD 1 - $f"; done but how do I make it name based on the folder it is in and make it recursive?


Thank yall

https://redd.it/1pluwfp
@r_bash
Automate the initial creation process of your bash noscript

Tired of the initial hassle of creating a Bash noscript—like making the file readable and executable? If so, this tool is for you.

https://github.com/Keys02/noscriptify

PS: noscriptify also adds the shebang line.

All contributions are welcome

https://redd.it/1pm5vaw
@r_bash
Concurrent, parallel, or simultaneous?

I frequently write noscripts that should only have 1 instance running at a time. For instance, a noscript that copies a MySQL table from 1 host to another.

I implement this with a snippet like:

# prevent simultaneous execution                                                                                                                                             
pids=$(pidof -o '%PPID' -x "$(basename "$0")")
if [[ -n "${pids}" ]]
then
echo "$(basename $0) (${pids}) is already running."
exit
fi

Would you consider the second instance of this noscript to be concurrent, parallel, or simultaneous?

https://redd.it/1pmte90
@r_bash
Bash noscript for docker monitoring

I wanted to monitor and manage docker containers on a few servers. All the solutions I found were either heave or were missing things which I wanted so I started developing my own bash noscript - it started as a simple noscript but after many imitations and improvements based on usage it has become a real helpful tool.

Just wanted to share here in appreciation of Bash - there is so much which I did not even know can be done with simply bash noscripting.

https://github.com/buildplan/container-monitor

https://redd.it/1pnlqlx
@r_bash
change color in css file (working)

i have this simple bash file, to run you do for example "./test.sh accent \\#ffffff", but i want to merge the functions into one. how to do this?

https://preview.redd.it/87w1mp1q6g7g1.png?width=1281&format=png&auto=webp&s=c510c57cc1727e1e94613841bb6dd5281da41d74



https://redd.it/1pnloa1
@r_bash
Asking for help with a command launcher noscript

I'd like to ask a question about an automation strategy which has eluded me.

# What I'm trying to do

I'd like to have a noscript which:

1. can launch a new terminal emulator
2. then run a login shell in the terminal emulator (with all my personal shell initialization)
3. can then run an arbitrary program or command of my choosing
4. then on completion or termination of the program the shell stays alive and interactive
5. also the arbitrary command is added to shell history

Hopefully I explained that well.
Unfortunately something like alacritty -e bash -c 'echo hello' does not fulfill these requirements.
With the above the terminal is closed after program completion and is not run with shell initialization (login shell).

I'll share my solution, but I'm curious if there is an easier way to accomplish the same:

# Current Solution

I also put the code in this repo

I add the following to the end my ~/.bashrc

if [ -n ${INIT_CMD} ]; then
print -s "${INITCMD}"
eval "${INIT
CMD}"
unset INITCMD
fi

then to launch programs I use something like:

#!/usr/bin/env bash

# terminal='alacritty'
# terminal='ghostty'
# terminal='st'
terminal='kitty'

${terminal} -e
$SHELL \
-c 'INIT
CMD="echo hello" $SHELL'

where echo hello is the "program"

Which does require starting up two shells, however, the first shell with -c flag is cheap. The second shell is the login shell.

Thanks in advance if you know a simpler way to accomplish this!

https://redd.it/1po6z4y
@r_bash
How to check if $var is in a list?

Imagine you have:

mylist=("foo" "bar" "baz")



How can you check if $var is in mylist?

I don't want to write a loop for that :-)

https://redd.it/1ppmxqf
@r_bash
Bash Trek: TNG, an Update to a Retro Terminal Game

One or two attentive readers may recall that a couple of months ago, I posted about a Bash version of the old Star Trek terminal game that I'd written, called Bash Trek.

Well - I've adapted it into a new implementation, Bash Trek: TNG which replaces the old typed command interface with mouse control.

Mouse reporting is an underused thing, I think. It's not hard to build simple menus or buttons for simple terminal applications.

https://preview.redd.it/uj9z4g3za18g1.png?width=708&format=png&auto=webp&s=4baa2d60360563fe9c27a2afc6c9f1fb0dd78d5d

https://preview.redd.it/gxmif3e0b18g1.png?width=708&format=png&auto=webp&s=1c685b49377dfcc68684033c7da5397618f2a346

Anyway: if interested, https://github.com/StarShovel/bash-trek-tng



https://redd.it/1pq3ihb
@r_bash