r_bash – Telegram
bash while loop over command output

Hi! i have this command:

aws ec2 describe-snapshot-tier-status --filters "Name=tag:MarkedForDeletion, Values=True" --region us-east-1 --profile default | jq -r '.SnapshotTierStatuses[\].LastTieringOperationStatus' | grep archival-in-progress | wc -l

I don’t remember how to work using the while, I need to run a command over and over again, when the result of the command I mention (aws cli) is less than 25.

​

Any helps?

https://redd.it/104a5rr
@r_bash
Bash noscript help

Hi everyone 😊. Hope you all enjoy your holidays!

I was in the creation of a noscript and I would like to add a small detail in my noscript but I am stuck on how I can do it. Let me show and explain this better.

#!/bin/bash

###########################
# Created by Diego Castro #
###########################
Help()
{
# Display Help
echo "This noscript will run the records for any domains."
echo
echo "Syntax: ./records.sh [-h|d|s|a|m] [-S]"
echo "Options:"
echo "h Prints Help section."
echo "d Argument for DMARC record."
echo "s Argument for SPF record."
echo "a Argument for A record."
echo "m Argument for MX record."
echo "S +short"
echo
}

DMARC(){
read -p "Domain: " dmarc
echo "----------------------------------"
dig txt _dmarc.$dmarc
echo "----------------------------------"
}

SPF(){
read -p "Domain: " spf
echo "----------------------------------"
dig txt $spf | grep -i spf
echo "----------------------------------"
}

ARECORD(){
read -p "Domain: " aRecord
echo "-----------------"
dig A $aRecord
echo "-----------------"
}

MX(){
read -p "Domain: " mx
echo "-----------------"
dig mx $mx
echo "-----------------"
}

while getopts ':hdsamS' OPTION;
do
case "${OPTION}" in
h) #This will display Help
Help
exit
;;
d) #For DMARC
DMARC
exit
;;
s) #For SPF
SPF
exit
;;
a) #For A record
ARECORD
exit
;;
m) #For MX record
MX
exit
;;
S) #SHORT
#Need to know what to do here
exit
;;
esac
done

So in this code I can gives the option of choosing DMARC for example. That would be ./records.sh -d. Everything good until there but I would like to specify the option in the CLI, something like this. ./records.sh -d [facebook.com](https://facebook.com) (or any domain) but I don't see how I can do that.

​

As well, another thing I would like to do is the possibility to add at the end of every result, this option +short. That would be with the +S option but I don't know how I can add it to every place there to get the option.

So, for example, if I run the noscript: ./records.sh -d [facebook.com](https://facebook.com) \-S, that would give this result:

10 smtpin.vvv.facebook.com.

Really appreciate the help and the time to help me guys.

https://redd.it/104rq1j
@r_bash
How to using environment variables in jq replace command

This jq lookup command works using the --arg flag to use an environment variable -

jq --arg newval "$VARIABLE" '.environments.dev.kafkaVersion |= $newval' xena.json

Yet when I try to use the --arg flag in a jq replace command it returns a compile error -

TARGET_ENVIRONMENT="dev"

jq --arg environment "$TARGET_ENVIRONMENT" -r '.environments.$environment.kafkaVersion' xena.json

The same command without using the --arg to use a variable does work:

jq -r '.environments.dev.kafkaVersion' xena.json

What am i doing wrong here?

https://redd.it/104ug7x
@r_bash
suggestions to refine admittedly clumsy scrip

This:

#!/bin/bash

IFS=$'\n'

echo -n "suffix: "
read o in $STDIN

for i in *."$o" ; do exiftool "$i" | grep -i duration > "$i".duration ; done
for d in *.duration ; do sed -s 's/Duration : 0://' -i "$d" ; done
for d in *.duration ; do sed -s 's/ (approx)//' -i "$d" ; done
for f in *."$o" ; do renamexm -s/."$o"/\ \[`cat "$f".duration`\]."$o"/ "$f" ; done
rm -fv *.duration

1) is inelegant, and

2) functions with wav flac ogg mp3 but fails with m4a and mp4 files, truncating the final ]."$o"

3) Is exiftool inaccurate, or am I seeing artefacts of codec litter? I regularly get *very* different durations from a source wav and its compressed children [esp. mp3, but sometimes ogg. flac is usually not off by more than 1s, if at all].

Thanks for any suggestions, pointers, especially those that are *simple* as I am still quite new to this. :)

https://redd.it/10581xl
@r_bash
help prefer to have editable input

I wrote this super simple helper...

#!/bin/bash

IFS=$'\n'

echo -n "artist: "
read a in $STDIN
echo -n "noscript: "
read t in $STDIN
echo -n "year: "
read y in $STDIN

mkdir -p "$a"/"$t""$y"
cd "$a"/"$t"
"$y"

pwd ; echo ready.

... but if I make any mistake typing, backspace just adds "\^H" instead.

How can I fix this?

https://redd.it/1057eua
@r_bash
Radio Streamers Using Rofi and Fzf
https://redd.it/101sdpb
@r_bash
Reclusively touching a file in each directory

I'd like to go down a directory structure and touch a file and add some content inside the file I touch, as such:

filename : desktop.ini

content:
Logo=$currentdirectorypath\1.jpg

Please and thanks

https://redd.it/105j8f0
@r_bash
Help with this command

I am trying to code a loop that removes all files excluding .jpg and .png from several drives. The loop is to change the number of the directory. In other words, I have directories with name recup-dir.i, where i is a number that increases by 1, and I want this loop to remove all files inside them going 1 by 1. I coded it like this:

​

\#!/bin/bash

for i in {85..90}

do

cd recup-dir.{i}

rm -v !(*.jpg|*.png)

cd ..

done

​

However, it results in a syntax error. I am a total beginner in Linux. Can you help me solve this issue, please?

https://redd.it/105m20u
@r_bash
An extended which alias

Hello guys. I found this reddit yesterday. It's nice.

Thought I'd share an alias fresh from the press. I use aliases, and it is cumbersome to have to use `alias` and `which` / `which -a` to figure out what is going on, at times, so, I made a `which alias` that caters for both cases, and thereby having a centralized point of inspection, and here it is:

alias which='f() { [ $# -eq 2 ] && SEARCH=$2 || SEARCH=$1 ; alias $SEARCH &>/dev/null && alias $SEARCH; \which $* ; unset -f f ; } ; f'

It prints out any alias you may have made for the command, before you get either the command that is first in the path with that name, or all, in order of appearance of the path.

`man which`

This command, only applies to those, that doesn't have aliases returned by `which`, and if you prefer it as a shell noscript, it should be easy to rework it.

**Edit**

Here is the accompanying `what` command, that displays the noscript, or alias, by a construction like this:

what ` which what`

Here is `what`

#!/bin/bash
file "$1" | grep ASCII >/dev/null
if [ $? -eq 0 ] ; then
batcat --style="header" --theme "$BATCATTHEME" $(which $1)
else
[ -f "$1" ] && file $1 || echo "$1" alias >/dev/null && echo $@
fi




Enjoy, and thank you for your contributions.

https://redd.it/105msez
@r_bash
Sshto update

Happiu-piu New Year to all!

Guess everyone stepped into this:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
...

And most of the time it's not something nasty but reinstalled VM or server. To fix this you had to remove host from known\_hosts file and then set it back. I've automated this process in sshto via Fix\_id command:

sshto commands list

Have fun!)

https://redd.it/105umac
@r_bash
"Polus" A new amazing theme for Bash

If you are looking for a good-looking, fast and lightweight theme for Bash, then you must use "Polus". Its fully written in Bash under 60 lines of code and doesn't require additional dependencies.

https://github.com/rashed145/polus-bash-theme

https://redd.it/105z38u
@r_bash
Question for an example in the oreillys book on bash?

What does it mean if there is just a string, no other test arguments in square brackets. What is it testing for?

The image/code I am referring to is : https://imgur.com/a/7D1HirV

https://redd.it/10664i2
@r_bash
PS1 exit code function

I have been customizing my PS1 and I only want an error code to populate if it is non-zero. I wrote a simple function that works if I call it from the CLI but in the PS1 it always returns as 0. I'm thinking because the other functions/noscripts running in PS1 are exiting 0. How do I work around this or am I just wrong...lolz.

PS1='\[$(tput sc; rightprompt; tput rc)\][\A] [\w] `RAM_USE``CPU_USE`\n`EXIT_CODE`-->'

function EXIT_CODE {
if [[ $? = 0 ]]; then
sleep 0
else
echo "[$?]"
fi
}

https://redd.it/106gygr
@r_bash
Can't properly execute Bash variable as options

I have a [noscript](https://gist.github.com/mbierman/6cf22430ca0c2ddb699ac8780ef281ef) that defines a variable that becomes equal to the following. This variable , "args" includes other variables which have to be expanded to complete it.

--name=homebridge --hostname=homebridge --env=HOMEBRIDGE_CONFIG_UI_PORT=8581 --env=PATH=/opt/homebridge/bin:/var/lib/homebridge/node_modules/.bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin --env=S6_OVERLAY_VERSION=3.1.1.2--env=S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 --env=S6_KEEP_ENV=1 --env=ENABLE_AVAHI=0 --env=USER=root --env=HOMEBRIDGE_APT_PACKAGE=1 --env=UIX_CUSTOM_PLUGIN_PATH=/var/lib/homebridge/node_modules --env=HOME=/home/homebridge --env=npm_config_prefix=/opt/homebridge --env=npm_config_global_style=true --env=npm_config_audit=false --env=npm_config_fund=false --env=npm_config_update_notifier=false --env=npm_config_loglevel=error --env=HOMEBRIDGE_PKG_VERSION=1.0.33 --volume=/volume1/docker/homebridge:/homebridge:rw --volume=/homebridge --network=host --workdir=/homebridge --restart=always --label='org.opencontainers.image.noscript=Homebridge in Docker' --label='org.opencontainers.image.authors=oznu' --label='org.opencontainers.image.licenses=GPL-3.0' --label='org.opencontainers.image.url=https://github.com/oznu/docker-homebridge' --label='org.opencontainers.image.denoscription=Official Homebridge Docker Image' --log-driver=db --runtime=runc --detach=true -t oznu/homebridge:ubuntu

The variable is defined perfectly and returns what I need and expect.

I then want to execute the arguments in $args, like so:

`sudo docker run "$args"` or `sudo docker run $args`

The problem is I get

sudo docker run '
--name=homebridge --hostname=homebridge --env=HOMEBRIDGE_CONFIG_UI_PORT=8581 --env=PATH=/opt/homebridge/bin:/var/lib/homebridge/node_modules/.bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin --env=S6_OVERLAY_VERSION=3.1.1.2--env=S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 --env=S6_KEEP_ENV=1 --env=ENABLE_AVAHI=0 --env=USER=root --env=HOMEBRIDGE_APT_PACKAGE=1 --env=UIX_CUSTOM_PLUGIN_PATH=/var/lib/homebridge/node_modules --env=HOME=/home/homebridge --env=npm_config_prefix=/opt/homebridge --env=npm_config_global_style=true --env=npm_config_audit=false --env=npm_config_fund=false --env=npm_config_update_notifier=false --env=npm_config_loglevel=error --env=HOMEBRIDGE_PKG_VERSION=1.0.33 --volume=/volume1/docker/homebridge:/homebridge:rw --volume=/homebridge --network=host --workdir=/homebridge --restart=always --label='\''org.opencontainers.image.noscript=Homebridge in Docker'\'' --label='\''org.opencontainers.image.authors=oznu'\'' --label='\''org.opencontainers.image.licenses=GPL-3.0'\'' --label='\''org.opencontainers.image.url=https://github.com/oznu/docker-homebridge'\'' --label='\''org.opencontainers.image.denoscription=Official Homebridge Docker Image'\'' --log-driver=db --runtime=runc --detach=true -t oznu/homebridge:ubuntu'

which fails. Obviously I'm not escaping something properly or something like that but I'm not seeing how to solve it.

If I simply echo the entire command rather than executing it, it comes out fine and if executed, works but I want this to work interactively.

sudo docker run --name=homebridge --hostname=homebridge --env=HOMEBRIDGE_CONFIG_UI_PORT=8581
--env=PATH=/opt/homebridge/bin:/var/lib/homebridge/node_modules/.bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin --env=S6_OVERLAY_VERSION=3.1.1.2 --env=S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 --env=S6_KEEP_ENV=1 --env=ENABLE_AVAHI=0 --env=USER=root --env=HOMEBRIDGE_APT_PACKAGE=1 --env=UIX_CUSTOM_PLUGIN_PATH=/var/lib/homebridge/node_modules --env=HOME=/home/homebridge --env=npm_config_prefix=/opt/homebridge --env=npm_config_global_style=true --env=npm_config_audit=false --env=npm_config_fund=false --env=npm_config_update_notifier=false --env=npm_config_loglevel=error --env=HOMEBRIDGE_PKG_VERSION=1.0.33 --volume=/volume1/docker/homebridge:/homebridge:rw --volume=/homebridge --network=host --workdir=/homebridge --restart=always --label='org.opencontainers.image.noscript=Homebridge in Docker' --label='org.opencontainers.image.authors=oznu' --label='org.opencontainers.image.licenses=GPL-3.0' --label='org.opencontainers.image.url=https://github.com/oznu/docker-homebridge' --label='org.opencontainers.image.denoscription=Official Homebridge Docker Image' --log-driver=db --runtime=runc --detach=true -t oznu/homebridge:ubuntu

https://redd.it/106vxnb
@r_bash
Escape Whitespace in command not working

Why is this not working?

$ touch "this is a test"
$ echo "./this is a test" | sed -e 's/^a-zA-Z0-9,._+@%-//\\&/g'
./this\ is\ a\ test
$ rm "$(echo "./this is a test" | sed -e 's/^a-zA-Z0-9,._+@%-//\\&/g')"

but this does

$ rm ./this\ is\ a\ \ test

https://redd.it/106ulbu
@r_bash
SCREAMINGCASE variables - is it really essential?

I read someone who mentioend that if you don't use SCREAMING\
CASE then you have zero chance of accidently overwriting important environment variables. Also I find camelCase a lot nicer to read.

For that reason, I always use camelCase for my own variables, but will continue to use SCREAMING_CASE for environment variables

What's your thoughts?

https://redd.it/107aw18
@r_bash
A function that uses coprocs to parallelize loops in a way that is orders of magnitude faster than forking

LINK TO CODE ON GITHUB

I wrote a function that parallelizes a loop using bash coprocs instead of forking. To run N tasks at a time, the code forks off N coprocs and then pipes data to them, passing a new input each time one finishes its current task.

The syntax is much like the basic usage of xargs -P or parallel. for example: finding the sha256sum of all files under the current path is done via:

source /path/to/forkruncoproc.bash
find ./ -type f | forkrun
coproc sha256sum

Why would you want to use this over standard forking / xargs -P / parallel? Well, a couple of reasons:

1. Its a pure-bash solution - no external dependencies are required (with the exception of printf, but its hard to imagine a system that has bash but not printf). NOTE: bash 4.0+ is needed, since this is when coprocs were introduced into bash.

2. It is fast.

It is so fast because forking has a lot of overhead - see man fork(2) for all the stuff that is copied into the child process during a fork syscall. To run a function with M different inputs using N parallel processes:

traditional forking requires `M` fork syscalls, plus `M` calls to `jobs -r | wc -l` to control the number of active current forks.

using forkruncoprocs only requires `N` forked coprocs. Once these are setup, data is passed to/from them without additional forks.

This means that, in particular for loops that have numerous inputs to parallelize over but where each individual input runs very fast, there is a HUGE speed increase. How huge? Heres an example:

On my machine I tested/timed computing the sha256sum of every file under `/lib*/`. (which are symlinks to /usr/lib* on my machine). This comes out to about ~85k files, most of which are very small (and as such computing their sha256sum is very fast for each individual file). Here's how standard forking / paralel / xargs -P / forkrun
coproc performed (on an admittedly beefy 28-core i9-7940x-based machine running fedora):

runcontrolledfork() {
mapfile -t inArgs < <(find /usr/lib -type f)
nArgs=${
#inArgs[@]}
nProcs=$(which nproc 2>/dev/null 1>/dev/null && nproc || grep -cE '^processor.
: ' /proc/cpuinfo)
for nn in "${inArgs@}"; do
sha256sum "$nn" &
(( $(jobs -rp | wc -l) >= ${nProcs} )) && wait -nf
done
}

runparallel() {
find /usr/lib* -type f | xargs -l1 -P$(which nproc 2>/dev/null 1>/dev/null && nproc || grep -cE '^processor.*: ' /proc/cpuinfo) sha256sum
}

run
xargs() {
find /usr/lib -type f | parallel -j $(which nproc 2>/dev/null 1>/dev/null && nproc || grep -cE '^processor.: ' /proc/cpuinfo) sha256sum
}

runforkruncoproc() {
find /usr/lib -type f | forkrun_coproc sha256sum
}

time run_controlled_fork

real 28m16.651s
user 20m21.887s
sys 32m26.817s

time run_parallel

real 3m59.612s
user 5m46.280s
sys 9m19.121s


time run_xargs

real 1m24.514s
user 1m30.911s
sys 3m44.941s


time run_forkrun_coproc

real 0m18.589s
user 1m14.336s
sys 2m45.950s

In terms of real-world execution time, `forkrun_coproc` was

\~91x faster than simple forking (just shy of 2 orders of magnitude)
\~13x faster than `parallel`
\~4.5x faster than xargs -P

forkrun_coproc, was also the lightest on cpu cycles used (followed close-ish-ly by xargs -P).

https://redd.it/107f1mw
@r_bash
I give up: WTF is #ifs!

23 years of Bash and today I come across this in code I need to maintain. Very first line is:

\#ifs!/bin/bash

What the hell is #ifs doing before the ! ? Googling stuff like this is pretty futile; can anyone enlighten me?

EDIT: The answer is - this is a typo which someone made and is the reason I had to look at the noscript in the first place! Duh! Git history to the rescue!

https://redd.it/107i7vx
@r_bash