r_bash – Telegram
Learning Tracks and Certifications

Hi All,

I am trying to gain deeper knowledge on all things Bash, starting with noscripting (I am already proficient with normal use/commands). I took the course from Codecadeny and that was great because it provided excercises and a mock shell that provided guidance on debugging and feedback on errors.

This seems to be very common for programming languages, but most learning websites I can find are strictly audiovisual, with limited excercises and they just provide answers, no interactive shell to debug with.

Is anyone aware of any courses similar to the codecademy one please? Further, are there any certifications or highly rated courses specific to Bash anyone could please recommend? Its fine if these courses are not free.

Im in an industry where navigating Bash is critical and being able to noscript could really improve my earning potential, but there is no benefit right now to taking the next step into a full programming language.

Thanks in advance.

https://redd.it/zgu5bb
@r_bash
Emojis in your PS1! Create a christmas themed PS1

To create a Christmas-themed bash prompt, you can use the PS1
variable to customise your prompt. For example, you could use the following bash code to create a prompt that includes a Christmas tree, some snowflakes, and the current time:

PS1="\n🎄 $(date +"%T") \n☃️ "

This code sets the PS1 variable to a newline, a Christmas tree emoji, the current time in 24-hour format, another newline, a snowflake emoji, and a space.

You can also add additional elements to the prompt, such as the current working directory or your username, by using the \\w and \\u escape sequences, respectively. For example:

PS1="\n🎄 \u@\h \w $(date +"%T") \n☃️ "

This code adds the username and hostname to the prompt, as well as the current working directory.

You can add this code to your .bashrc file to make the changes permanent.

Please note that the appearance of the prompt may vary depending on the font and terminal emulator you are using. Emojis may not display properly on all systems.

Works great in Gnome Terminal though:

​

https://preview.redd.it/eypze1v01v4a1.png?width=456&format=png&auto=webp&s=ddb629fd5fa0e29dcd328567e8f0ab74b9d3244a

This post was written as part of my #FoodBankFriday efforts to raise money for my local foodbank. If you found it interesting or useful and would like to show a little appreciation - a small donation would be gratefully recieved!

https://www.justgiving.com/page/fbf-joseph-edmonds

https://redd.it/zgv3l7
@r_bash
Assistance using sed and regex to filter printer queue names

Look for a bit of sed/regex manipulation help here.


Im trying to use the lpstat command to get a list of specific print queues. Once I get a found set of queue names, they will be deleted later.


Criteria

\-Only display the queues that do NOT contain "_IPP" at the end of the queue name (these queues do not need to be deleted later) Im using grep for this now which works.
\-Only display queues that start with "mfp" or "p" (these are my 2 targets to delete later) Trying to use sed but not working.


So in a nutshell, I want to see only printers with the prefix "mfp" or "p" that do NOT contain the "_IPP" suffix.



Example that fails:


queues=$(lpstat -p 2>/dev/null | grep -v _IPP | awk '{print $2}' | sed '/\^mfp/; /\^pb/; /\^pc/')

echo $queues

sed: 1: "/\^$/d; /\^mfp/; /\^pb/; / ...": invalid command code ;

https://redd.it/zh2ouu
@r_bash
Trying to print binary/hex data to file

I am trying to write a noscript that dumps memory contents to a file. I am getting all the data, but can’t figure out how to format it. I am using devmem2 to read 32-bit registers on an embedded linux system. Here is part of the noscript:

rwmem(){
if [[ $# -eq 1 ]]
then
devmem2 $1 | grep ':' | awk -F ': ' '{print $2}'
else if [[ $# -eq 2 ]]
then
devmem2 $1 w $2 > /dev/null
else
echo "Usage: rwmem <address> [write_value]" >&2
echo "Without a write value, this command will read. This command uses devmem2 but with reduced verbosity." >&2
fi
fi
}

VIDEO_BUFF0=0x19000000

#### DUMP DDR CONTENTS TO FILE:
echo "Dumping DDR to file..."
for (( i=0; i<9216; i++ ))
do
rwmem $(( $VIDEO_BUFF0 + i*4 )) >> "ddr_dump.raw"
done
echo "Dumping DDR to file...DONE"

I am not sure how to ask my question exactly, because this stuff is new to me. I want to write the contents as either 16 or 32 bit binary numbers. When I open the ddr\_dump.raw file in notepad++, this is what I see:

&#x200B;

https://preview.redd.it/eck7261w0y4a1.png?width=215&format=png&auto=webp&s=883f49ad637c6dc146252eedf28c06107c8fcd49

This is all the correct data, but when I open it in a hex editor, it looks like this. It is interpreting my values as ASCII values, not as hexadecimal numbers:

https://preview.redd.it/bq9uko1z0y4a1.png?width=890&format=png&auto=webp&s=d6de1507d3c72d14a97a27d27404111626410182

But I want it to look similar to this (little endian):

https://preview.redd.it/ectabvl01y4a1.png?width=895&format=png&auto=webp&s=41cdaddd1e03b2b95ac4d05b938a3241706c4838

I apologize in advance, I don’t know exactly how to word this question but I want to write 16 or 32 bit binary or hex data to a file and read it in a hex editor I guess.

Thanks in advance for your replies, but bear in mind I am very new to bash noscripting. I know there is probably a better way to do this with C or some other language, but It doesn’t need to be an elegant solution and this is just a tool for me to use.

https://redd.it/zh9vqo
@r_bash
Exit code confusion

I just encountered what seems like bizarre behavior, which means I don't fundamentally understand the tool I'm using: in this case what I thought was the simplest thing in the book: exit codes.

Here's what I'm trying to do: I run a nightly rsync from multiple systems to my NAS, and I want to get a Slack message if something goes wrong. However, I want to ignore exit code 24 (the "files vanished") error. Here's what's blowing my mind: the order in which I test the exit codes seems to matter. Here's some example code (with ls just to make it easier to test; just assume that I want to ignore both the zero (success) exit code as well as exit code 1 instead of 24).

The version that does exactly what I want:

ls

if (( $? != 1 )) && (( $? != 0 ))
then echo "Send slack"
fi


In that example, if I change the command to something that throws an error code 1 (e.g. ls aoeu) it won't print the echo. However, if I change ls to a nonexistent command like, say lsl I get the echo because the shell sets the exit code to 127. So, works exactly like I'd expect.

Now, if I just switch the order of the tests like this: if (( $? != 0 )) && (( $? != 1 )), I'll get the echo when trying ls aoeu. It still correctly ignores the echo command when the exit code is zero.

So, my fellow Redditors: what the heck is going on? Why would the order in which I run the test matter at all?

Interestingly, if I assign the exit variable to a shell variable and test that, it works in either order. That's the path I've taken for now, since it's better practice anyway. But I'm intensely curious why my original approach didn't work. Makes me think I really don't understand how the $? variable works, or I don't understand the tests I'm using.

https://redd.it/zhmh6c
@r_bash
Running noscript function from host in docker container

I'm working on yet another iteration of a backup noscript for some docker containers. I'm trying to dump a DB to a file in a directory in the container that's bound to the host so I can access that dump from the host. I'd like to define the dump command and arguments as a function in the backup noscript on the host then run the function via docker exec in the container. I don't know how to make bash send the body of the function into the container via docker exec. Currently it's passing the function name into the container where it then tries to exec a noscript by that name that doesn't exist in the container.

# Set some variables
date=$(date +"%y%m%d-%H%M")
bookstackDir="/home/myuser/docker/appdata/bookstack/"
dbDir="/home/myuser/docker/appdata/mariadb/"
bookstackArchive=${date}"bookstackArchive.tar"
bookstackDB=${date}"bookstackDB.sql"
backupGZ=${date}"bookstackGZ.tar.gz"
bookstack_db_container=$(/usr/bin/docker ps | grep bookstack_db | awk '{print $1}')
bookstack_app_container=$(/usr/bin/docker ps | grep lscr.io/linuxserver/bookstack | awk '{print $1}')
appRoot="/app/www/"
dockerDir="/home/myuser/docker/"

#Declare some functions
function dbdump()
{
mysqldump --defaults-file=/root/.secrets/bookstackCreds.cnf --all-databases > "/archive/""${bookstackDB}"
}

function archive()
{
tar --create --file /archive/"${bookstackArchive}" ${appRoot}"public/" ${appRoot}".env" ${appRoot}"storage/"
}

# Dump the mariadb to a shared directory
docker exec "${bookstack_db_container}" dbdump
docker exec "${bookstack_app_container}" archive

&#x200B;

# ./bookstackArchive.sh
OCI runtime exec failed: exec failed: unable to start container process: exec: "dbdump": executable file not found in $PATH: unknown
OCI runtime exec failed: exec failed: unable to start container process: exec: "archive": executable file not found in $PATH: unknown

https://redd.it/zhm04z
@r_bash
How to clean this up?

cd $HOME/Scripts || { echo "Scripts directory does not exist"; exit 5; }
if test -f "$1"; then
echo "$1 already exists"
exit
fi

touch "${1}"
chmod +x "${1}"
echo -e "#!/bin/bash\\n" > "${1}"
echo -e "## ${1}\\n" >> "${1}"
echo -e "## $(date +"%D %T")\\n" >> "${1}"
read -p "Script's purpose: " purpose
echo -e "## $purpose\\n" >> "${1}"
vim '+normal Go' "${1}"
echo "New BASH noscript name:" "$1"

https://redd.it/zhyv8u
@r_bash
Assign conditional test to variable?

I want to assign the result of a conditional test to a variable. How do I accomplish in bash?

I understand if syntax

if some_condition

I don't know how to move that into a variable

# Does this work?
$variable=some_condition

https://redd.it/zi0ddk
@r_bash
Is there a way to alias a global disabling of all bash functions for a single command?

So, the reason I ask this is because I got tired of not being able to do math in the command line so I made a python noscript called math that, well, does math. But the problem is I have to quote everything for bash to not complain, and it's super frustrating. Already I'm missing quotes all the time and having to redo things.

An example is to evaluate the number 123 into binary. I can now type math bin(123). But then I get a bash: syntax error near unexpected token '('. Similarly with say math round(34 + sqrt(13), 2). You get the picture.

I've looked and I can't find anything clear on this. Is there anyway to do this? I suspect not but I want to ask because it would be so amazing. Something where I can alias, in pseudocode: turn off all bash reading of things; read input line; pipe to math noscript; turn back no bash reading of things. I guess what I'm really asking for is a way to really just take the input string as raw, with nothing else to it.

Thank you! I totally understand if the answer is "impossible", I just want to exhaust all options before resigning myself to quote hell.

Edit: fixed markdown.

https://redd.it/zi1z9e
@r_bash
How to convert a txt file to one line with escape characters

I'm trying to make my text file look like this:

test\nim a new line\nso am i!


instead of this


test
im a new line
so am i!

How can I do that in the command line of bash?

All help is appreciated, thank you!

https://redd.it/zi66z2
@r_bash
How do I read a variable to replace it with a placeholder?

Assume I have the following in my noscript file:

export myvar=placeholder

I want to run the noscript and be asked the value of the $myvar, and then have it fill and replace the word "placeholder".

Any suggestions? I don't have to have the word "placeholder" I can leave it blank, if it is easier.

https://redd.it/zi3z5x
@r_bash
Newbie in bash noscript

How to send a picture with notification with a button working I tried notify-send but can't make a button using that.

https://redd.it/ziewvs
@r_bash
How to send a picture with notification with a button working I tried notify-send but can't make a button using that.



https://redd.it/zig8a8
@r_bash
Shell toolkit alternative without overlapping functionality

Is there similar to sed, awk, grep, cut and other similar tools without overlapping functionality? I need some set of atomic commands each doing one task, not several, just one. I prefer readability over short syntax also. It means that I prefer awk instead of sed. When I use cat, grep I feel that it's pointless in some way as they do what awk can. By all means, it's faster to use grep or cat to search smth or print file contents respectively. But it leads to the problem where you memorize more commands and know less about each of them, you spread all your energy on several commands instead of learning few deeply.

https://redd.it/zik3el
@r_bash
Why use the test command?

Over the last few days I've seen comments suggesting that the OP use test. I see some examples like:

if test -f "$1"; then

But what advantages does that have over using:

if [ -f $1 ]; then

When would you need "if test" instead of "if"?

https://redd.it/zimjju
@r_bash
How to make yq to produce nothing for missing keys instead of null?

I wanna load my yaml based config in my bash noscript via yq like this:

corefunctionloadmessagecolordefaults() {
INFO
COLOR="${INFOCOLOR:-green}"
WARN
COLOR="${WARNCOLOR:-yellow}"
ERROR
COLOR="${ERRORCOLOR:-red}"
}

declare config
name="$HOME/bash-settings.yml"

if ! which yq > /dev/null; then
warn "no 'yq' command found to load info, warn, error colors; defaults have been loaded"
corefunctionloadmessagecolordefaults
elif [[ ! -e "$config
name" ]]; then
warn "no '$configname' file found to load info, warn, error colors; defaults have been loaded"
core
functionloadmessagecolordefaults
else
INFOCOLOR="$(yq ".messages.info.foreground" "$configname")"
WARNCOLOR="$(yq ".messages.warn.foreground" "$configname")"
ERRORCOLOR="$(yq ".messages.error.foreground" "$configname")"
corefunctionloadmessagecolordefaults # Some value can be missing in config in which case default value must be used.
fi

unset config
name


But the problem is when I yq encounters missing keys in $config_file it prints null. By all means I can change my code to check whether variable's value is "null" string and then set it to default if it's true but I don't like this decision and unsure whether there is smth better.

https://redd.it/ziymto
@r_bash