r_bash – Telegram
Issues with white spaces in file names

Bash noob here. I have a bunch of numbered directories that contain unremembered files. I want to create a noscript that renames files within each directory starting with the number of their parent directory. So from this :

.
├── 1-folder
│   ├── files1
│   ├── files2
│   ├── files3
│   └── files4
├── 2-folder
│   ├── files1
│   ├── files2
│   ├── files3
│   └── files4


I want to get this :

├── 1-folder
│   ├── 1-files1
│   ├── 1-files2
│   ├── 1-files3
│   └── 1-files4
├── 2-folder
│   ├── 2-files1
│   ├── 2-files2
│   ├── 2-files3
│   └── 2-files4



I created a noscript and it works if the directories and files don't have any space

for d in ; do
num=$(echo $d | cut -d'-' -f1)
for f in "$d"/
; do
mv $f $d/${num}-$(basename $f)
done
done

But I get an error when trying to do the same for directories that contain white spaces

.
├── 1- folder
│   ├── files 1.png
│   ├── files 2.png
│   ├── files3 3.mp4
│   └── files4 4.mp3
└── 2- folder
├── files 1.mp3
├── files 2.png
├── files 3.jpeg
└── files 4.pdf

error :

mv: target 'folder/1-' is not a directory

https://redd.it/xhrqg1
@r_bash
Script that runs every second-last sunday of every month

Hi everyone, i'm trying to create a noscript that run a command every second-last sunday of every month.

until now i'm here:

#!/bin/bash

d=$(date +%Y-%m-%d) echo "$d"

data=$(date +%Y-%m-%d -d '14 days') echo "$data"

nextmonth=$(date +"%B %Y" --date="$(date +%Y-%m) next month") echo "$nextmonth"

currentmonth=$(date +"%B" -d '14 days'="$(date +%Y-%m) next month") echo
"$current
month"

if $current_month -eq $next_month
then
echo "SCRIPT START"
else
echo "SCRIPT DON'T START"
fi

Can you help me and telling me what i'm doing wrong?

https://redd.it/xi9laz
@r_bash
Bash Game of Life (problem with neighbor detection)

GitHub - Bash Game of Life (WIP)

I've made the Game of Life in Python, but also wanted to write it in Bash since I'm new to it and want to get a feel for working with it. It was going okay until I started to test and make sure the correct next state is created, but it's having problems detecting neighbors on the bottom 3 cells and keeping alive cells that should remain alive.

I've set 3 cells in an L shape so that the next state will create a new cell inside of the L. The new cell is created, but the first 3 cells I had preset would disappear.

I've added a bunch of debug echo lines in the next_board function to show when/where neighbors are detected. The first cell that it checks (top-left) should have a neighbor on the bottom-right, but it doesn't. By the 8 or 9th cell, it starts to detect neighbors.

TLDR: Problems detecting any bottom 3 neighbors and keeping cells alive that are supposed to remain alive.

https://redd.it/xindh5
@r_bash
Bash Game of Life (problem with neighbor detection)

GitHub - Bash Game of Life (WIP)

I've made the Game of Life in Python, but also wanted to write it in Bash since I'm new to it and want to get a feel for working with it. It was going okay until I started to test and make sure the correct next state is created, but it's having problems detecting neighbors on the bottom 3 cells and keeping alive cells that should remain alive.

I've set 3 cells in an L shape so that the next state will create a new cell inside of the L. The new cell is created, but the first 3 cells I had preset would disappear.

I've added a bunch of debug echo lines in the next_board function to show when/where neighbors are detected. The first cell that it checks (top-left) should have a neighbor on the bottom-right, but it doesn't. By the 8 or 9th cell, it starts to detect neighbors.

TLDR: Problems detecting any bottom 3 neighbors and keeping cells alive that are supposed to remain alive.

https://redd.it/xindh5
@r_bash
how do we write a bash noscript to run python or pip commands.

Want to create a bash noscript to upload a custom package i created to pypi. Includes commands like
python setup.py sdist
Pip install twine
Twine upload dist/*
Twine upload must be able yo take user name and password as well.
Would be helpful if someone could point me towards any resource or example as I'm not familiar with noscripting.
Thankyou.

https://redd.it/xiyk0p
@r_bash
how do we write a bash noscript to run python or pip commands

Need to create a bash noscript that is able to upload a custom python package to pypi. Hence run python and pip command , also upload to pypi with the correct credentials.

Will something like this work if python is already installed in the environment i am running this.


#!/bin/bash
python setup.py sdist
pip install twine
twine upload dist/* -u 'username:password'

Nog familiar with bash, could someone point me towards any resource to do something like this.

https://redd.it/xiz6gc
@r_bash
Awk only processing the first word

I am trying to make a simple histogram for a text file.

declare -A letters

​

awk 'BEGIN{FS=""}

{letters[$(NR)]++}

END {for(letter in letters){print letter ":" letters[letter]}}' input.txt

input.txt has Hello world

but the output is only H:1 and no other letters.

Can someone point out where I messed up? I am still very new to awk.

https://redd.it/xisr2a
@r_bash
Help embedding a command into a noscript

I am trying to automate with bash noscripting a few commands that I use to report on some things. The command runs a select statement fed into the executable as arguments.

This seems to work in a command line:

for i in server1 server2 server3 server4; do runexec -se=$i "select SERVERNAME, SCHEDULEDSTART, ACTUALSTART, SCHEDULENAME, cast ((NODENAME) as char (60)) as NODENAME , cast ((STATUS) as char (15)) as STATUS from STATUS, EVENTS where STATUS <> 'Completed' AND STATUS <> 'Future' AND CURRENTTIMESTAMP - 15 HOURS < SCHEDULEDSTART" >> /tmp/report-$date; done

But when I try to modify it for use in a noscript, I get all sorts of errors:

for i in $serverlist;
do
/usr/bin/runexec -se=$i "select SERVERNAME, SCHEDULEDSTART, ACTUALSTART, SCHEDULENAME, cast ((NODENAME) as char (60)) as NODENAME , cast ((STATUS) as char (15)) as STATUS from STATUS, EVENTS where STATUS <> 'Completed' AND STATUS <> 'Future' AND CURRENTTIMESTAMP - 15 HOURS < SCHEDULEDSTART" >> /tmp/report-$date
done

Can you offer some (gentle) guidance as how I can integrate double quotes, single quotes, and round brackets into a command in bash noscript? I've tried using a \ delimiter around them all, curly brackets instead of round brackets, but I'm getting mismatch errors

https://redd.it/xjcgcx
@r_bash
How to output all lines of a file up to a specific character?

>filename.txt
>
>12.345.678.901/23
>
>13.456.789.01/24
>
>13.345.678.901/25

I want to make a new file that is everything before the /

>newfile.txt
>
>12.345.678.901
>
>13.456.789.01
>
>13.345.678.901

https://redd.it/xjb1tt
@r_bash
yq REPL using fzf

Hello "bash noscripts" experts,

I am a beginner: new to fzf, yq (yaml), and bash noscripts.


The purpose of my noscript: I want to search for given keys in all yaml files under the current directory.


All yaml files are in the following sample format.


- Keys:
- k1
- k2
- k3
- AnotherField1: Value 11
- AnotherField2: Value 12

- Keys:
- k1
- k3
- k4
- AnotherField1: Value 21
- AnotherField2: Value 22

- Keys:
- k3
- k4
- k5
- AnotherField1: Value 31
- AnotherField2: Value 32



If a user enters k1 for keys, the following records should be returned.


- Keys:
- k1
- k2
- k3
- AnotherField1: Value 11
- AnotherField2: Value 12

- Keys:
- k1
- k3
- k4
- AnotherField1: Value 21
- AnotherField2: Value 22




If the user further filters using k1,k3 for keys, the following record should be returned.

    
- Keys:
- k1
- k3
- k4
- AnotherField1: Value 21
- AnotherField2: Value 22




I need to fetch AnotherField1, AnotherField2 fields for the selected record.

The corresponding yq query on terminal looks like:



yq eval '.[] | select(.Keys.[] | select(.== "k1")) | select(.Keys.[] | select(.== "k3")) | (.AnotherField1, .AnotherField2) ' **/*.yml



Below is my non-fzf version noscript-name.sh. Pardon my lack of knowledge. Please feel free to suggest improvements in the code.


#!/usr/bin/env bash

while [ "$1" != "" ]; do
case $1 in
--keys )
shift
keys=$1
;;
-h | --help )
exit
;;
* )
exit 1
esac
shift
done


if [ -z $keys ]; then
echo "The keys field is required."
exit
fi

# Parse comma seprated (delimiter) keys, and store in an array.
IFS=',' read -r -a array <<< "$keys"


# I am trying to build filters for yq here.
yq_filter=""

for ((idx=0; idx<${#array[@]}; ++idx)); do
if [ "$idx" != 0 ]
then
yq_filter="${yq_filter} | "
fi

yq_filter="${yq_filter}select( .Keys.[] | select ( .== \"${array[idx]}\" ) )"
done

# All Yaml files
files=$( find . -name *.yml )

# Final command
command='yq eval ".[] | $yq_filter | (.AnotherField1, .AnotherField2)" $files'

eval "$command"



If I enter a command like below, the noscript works fine.



./noscript-name.sh --keys k1,k3




However, I would like to use the noscript as REPL with the help of fzf.

Could someone please help with the following code? I only found single query {q} examples, but I need to parse the query where the comma is used as a delimiter. Is it possible? If not, please suggest an alternative approach. Thanks.


#!/usr/bin/env bash

IFS=: read -ra selected < <(
FZF_DEFAULT_COMMAND="??" \
fzf --ansi \
--disabled \
--bind "change:reload:sleep 0.1; ?? || true" \
--delimiter : \
--preview-window 'up,60%,border-bottom,+{2}+3/3,~3'
)



I also intend to capture the result i.e. AnotherField1, AnotherField2 fields, and pass them into a bash function as arguments.



function someBashFunction(param1, param2) {
# param1 and param2 should be AnotherField1, AnotherField2 of the selected record.
}




I am not sure about what the following code should look like. Once a record is selected, the record's AnotherField1, AnotherField2 fields should be passed to the someBashFunction.


[ -n "${selected[0]}" ] && someBashFunction(??, ??)




Additional question:


Please also suggest how you debug fzf code, like how do I find out the exact command that was passed to fzf.

https://redd.it/xjgcwn
@r_bash
preserve history in the tmux session when you reconnect with ssh?

Is this even possible?

https://redd.it/xjjk1e
@r_bash
Output somehow "escaping" from inside variable

I'm trying to create a noscript for detecting the current song in quodlibet. It all works perfectly except for one strange thing: everything works, except when there's a certain output. Here it is:

&#x200B;

$ quodlibet --print-playing

Quod Libet is not running (add '--run' to start it)

&#x200B;

This output refuses to be assigned to a variable, and gets output into stdout.

&#x200B;

$ songstat=$(quodlibet --print-playing)

Quod Libet is not running (add '--run' to start it)

$ echo $songstat

[something else]

&#x200B;

If a song is playing, it works just fine

$ songstat=$(quodlibet --print-playing)

$ echo $songstat

Dean Martin - Mambo Italiano

&#x200B;

I'm puzzled. Is it the "--run" which is causing problems?

https://redd.it/xjg8xk
@r_bash
i need help with bash (18f)

we can be friends but please i really need help with this bash lab so kind of a tutor

https://redd.it/xjnywx
@r_bash
Need help with capturing date and time in my output

Hi all,

I made a shocking discovery today that my audit.log and rotations are not being uploaded. So I have about a years worth of rotations and I need to rename them based on their date. I created a noscript that is doing it pretty well but I also need to capture HH:mm:ss which I am struggling with.

for T in $(ls /var/log/audit); do TIMESTAMP=$(stat -c %y $T | awk '{ print $1 }'); mv $T audit-$TIMESTAMP.log; done

# Jun 14 2022 05:00 audit.log.500 -> audit-2022-06-14.log
# I want audit-2022-06-14-05-00.log

I found a sed command that does ALMOST what I need but I dont understand this command so I dont know how to edit it to pull what I need (its pulling HH:mm but not ss).

sed 's/.* \([0-9]*:[0-9]*\):[0-9]*.*/\1\'

Am I on the right track? I am too new at shell to full understand how to pull this off.

https://redd.it/xjnxji
@r_bash
How to check with xrandr if monitor has output

Hi everyone

I try to modify my launch.sh noscript for polybar such that it works for my multi monitor setup.

My problem is, that I have a laptop and in my home office I have two 27 inch monitors. So when I am at home I set via xrandr the --output of my laptop screen to --off.

Is there a way to detect if the monitor output is on or off?
Because now I have a noscript which starts for every connected monitor a polybar but my laptop screen still counts as connected even the output is off (which is correct of course).
I don't want to just exclude my laptop screen since I sometimes just use the laptop of course.

The only workaround which I can think of now, is to check if more than one Monitor is connected and if so exclude my laptop screen otherwise use it only there. But I wanted to know if there is a better way

Thank you

https://redd.it/xjxkof
@r_bash
There seems to be process occupying port 2181 which is Java

I'm trying to launch program zookeeper which use default port 2181, however it shows error saying that the address is being used.

After I test with netstat: netstat -tulpn | grep :2181


It shows this:

tcp6 1 0 :::2181 :::* LISTEN 279/java

&#x200B;

I'm not sure if this process is the Java program. If it is, then I couldn't shut the process down since I need it.

&#x200B;

Could anyone help me identify what process exactly is this? Thanks!

https://redd.it/xk6eb6
@r_bash
How do I make a condition based on whether $2 is set when I run my noscript?

So I have a noscript called vimcode that basically just sets up a project folder for my C++ code and starts writing in vim. I don't know if I have the most efficient way of writing it, but that part will be pretty clear once you read the noscript. That works, but I wanted to set up a second option that will start writing a file with a specific name because vimcode <project> will create <project>/<project>.cpp, so a specific file would be done with vimcode <project> example.h, I want this to create <project>/example.h

With how I have it currently written it opens up <project>/<project>.cpp even when I write the second option. However, the way I have it checking for the second option is with [[ -v $2 ]], I dont know if that is valid or not.

Here is what I have currently written

#!/bin/bash

CODEDIR="$HOME/Documents/code"

#Make project dir if it doesn't exit
if [ -d "$CODEDIR/$1/" ]; then
:
else
mkdir "$CODEDIR/$1"
fi

#Check for $2 before opening a file, open $2 if it is set
if [ -v $2 ]; then
nvim "$CODEDIR/$1/$2"
else
#If $2 is not set, open $1, if it does not exist, copy the template
if [ -f "$CODEDIR/$1/$1.cpp" ]; then
nvim "$CODEDIR/$1/$1.cpp"
else
cp "$CODEDIR/template.cpp" "$CODEDIR/$1/$1.cpp" && nvim "$CODEDIR/$1/$1.cpp"
fi
fi

https://redd.it/xka9mt
@r_bash
How to echo #!/bin/bash into a file

I want to use the echo command from the linux shell to create a file that has the line #!/bin/bash

At first I tried the command

echo -e "#!/bin/bash" >> file.txt

but this had a bash error for the ! so I tried

echo -e "#\!/bin/bash" >> file.txt

but this just makes a file with #\\!/bin/bash

What is the proper way to echo only #!/bin/bash into a file?

https://redd.it/xki11l
@r_bash
Looking for conceptual feedback on a noscript I am writing to update docker containers

I hope this isn't too much docker blah blah blah, but everything I'm writing is bash. I'm hoping there is some overlap that's acceptable here.

I realize watchtower exists, but I don't like it. I don't like not having control for how mature (how old) a docker image must be or individual control to potentially manipulate settings if I want. So the noscript I am writing has a minimum age that a repo must be before it is considered stable enough to install.

watchtower is written in Go. What I am working on is 100% bash. Here is the current output from my noscript as an example of what it is reading/scraping/comparing:

----

Repository Tag dAge Container iAge Status
---------- ---- --- --------- ---- ------
henrywhitaker3/speedtest-tracker latest 505 speedtest-tracker 505 SAME (1620136341=1620136341)
homeassistant/home-assistant stable 2 homeassistant 7 NEWER (1663544392>1663147322)
jez500/bender latest 13 bender 13 SAME (1662615615=1662615616)
openspeedtest/latest latest 6 openspeedtest 34 NEWER (1663260272>1660824207)
pihole/pihole latest 2 pihole 7 NEWER (1663584081>1663188503)
portainer/portainer-ce latest 6 portainer 16 NEWER (1663276762>1662412237)
r0gger/docker-wsusoffline latest 49 OFFLINE 49 SAME (1659478477=1659478477)
vaultwarden/server latest 56 vaultwarden 56 SAME (1658948175=1658948175)

Minimum dAge: 3
------------
Run Script: .\runScripts\openspeedtestRunScript.sh
Run Script: .\runScripts\portainerRunScript.sh

----

So, in this example, although there are (4) container images that have updates - only (2) of them are eligible for my noscript to process/update because I have set a minimum age requirement of (3). Right now the noscript isn't actually doing anything (because this is still a conceptual WIP), and I'm wondering (by asking you fine folks) if this is worthwhile endeavor or if I'm wasting my time.

My concept for the container-name-matched runScripts would be to directly issue docker run commands, docker-compose, etc. to facilitate an update. Here's an example:

----

#!/bin/bash
###### PI-HOLE (HOST:8125)
docker pull pihole/pihole:latest
docker stop pihole
docker rm pihole
docker run --detach \
--name pihole \
--restart unless-stopped \
--network host \
--hostname pihole \
--volume /volume1/docker/pihole/pihole:/etc/pihole \
--volume /volume1/docker/pihole/dnsmasq.d:/etc/dnsmasq.d \
--env WEBPORT="8125" \
--env DNSMASQ
LISTENING="local" \
--env DNSMASQUSER="root" \
--env DNSMASQ
PARAMS="--dns-forward-max=300" \
--env TZ="America/LosAngeles" \
--env VIRTUAL
HOST="pihole" \
--env PROXYLOCATION="pihole" \
--cap-add NET
ADMIN \
pihole/pihole:latest

----

My work so far is some local scraping and some repository scraping, mostly depending on jq, timestamp manipulation, and some basic math. I'm currently developing against unique container names and not image IDs. I'm probably going to personally run this no matter what, and the code will be hosted on GitHub at a later date.

So, is this concept good, bad, ugly, stupid? Give it to me as straight as can be. Thanks!

edit: The container marked as "OFFLINE" is actually offline. Its not actively running

https://redd.it/xkix1w
@r_bash
How exactly does ${!OPTIND} work in getopts?

I wrote a noscript to try and understand using long arguments in getopts, but don't really get what the ! operator is doing. If ${OPTIND} is the index value of the next argument, then how exactly does ${!OPTIND} work to get the value for --version?

while getopts 'abc:-:' OPT; do
echo -e "${OPT}\t${OPTIND}\t${OPTARG}"
case ${OPT} in
-)
case ${OPTARG} in
version)
echo "OPT: ${OPT}"
echo "OPTARG: ${OPTART}"
echo "OPTIND: ${OPTIND}"
echo "!OPTIND: ${!OPTIND}"
(( OPTIND++ ))
;;
esac
esac
done

Output:

$ ./test.sh -ab -c FOO --version 1.23
a 1
b 2
c 4 FOO
- 5 version
OPT: -
OPTARG:
OPTIND: 5
!OPTIND: 1.23

So, from what I can gather from the output, --version is at the fourth index, and 1.23 would be at the fifth index (which is why we use (( OPTIND++ )) to skip to the next argument, which would subsequently be positioned at the sixth index, if another argument were present). But how exactly is ! getting the value at the fifth index? From the documentation on shell expansion, it seems that this has something to do with indirect expansion:

&#x200B;

>If the first character of "PARAMETER" is an exclamation point, Bash uses the value of the variable formed from the rest of "PARAMETER" as the name of the variable; this variable is then expanded and that value is used in the rest of the substitution, rather than the value of "PARAMETER" itself.

Is this some kind of indirect expansion on an array?

https://redd.it/xkoi3u
@r_bash