Help with formatting multi line commands
Can someone kindly confirm if this is formatted correctly. I did hit the Format option on VSCode after installing shell-format extension but I am not sure
psql \
--tuples-only \
--command="SELECT 1 FROM pg_user WHERE usename = '${TARGET_POSTGRES_USERNAME}'" \
"""
dbname=${TARGET_POSTGRES_ROOT_DATABASE_NAME}
host=${TARGET_POSTGRES_HOST}
password=${TARGET_POSTGRES_PASSWORD}
port=${TARGET_POSTGRES_PORT}
sslmode=verify-full
sslrootcert=${POSTGRES_SSL_ROOT_CERT_PATH}
user=${TARGET_POSTGRES_ROOT_USERNAME}
""" | \
grep -q 1 ||
psql \
--command="CREATE USER ${TARGET_POSTGRES_USERNAME} WITH LOGIN NOSUPERUSER INHERIT CREATEDB NOCREATEROLE NOREPLICATION PASSWORD '${TARGET_POSTGRES_PASSWORD}'" \
"""
dbname=${TARGET_POSTGRES_ROOT_DATABASE_NAME}
host=${TARGET_POSTGRES_HOST}
password=${TARGET_POSTGRES_PASSWORD}
port=${TARGET_POSTGRES_PORT}
sslmode=verify-full
sslrootcert=${POSTGRES_SSL_ROOT_CERT_PATH}
user=${TARGET_POSTGRES_ROOT_USERNAME}
"""
https://redd.it/16rjrrz
@r_bash
Download Firewall Denied IP List using bash?
Hello Guys,
I want to save my firewall IP Denied list from my firewall to a local text file. I figured how to login and save the output of the first screen but got stuck.
I am hoping someone can help me I want to use a .sh script file to login to my firewall send several commands such as cli then show security match-policies denied. Which will result in a list that would normally require me to hit the Enter key over 100 times then save the results of the IPs that were denied access to a text file on my local server
https://redd.it/16r8zx8
@r_bash
New operator idea: inline loop operator
virsh start {{foo,bar,baz}}
for x in foo bar baz; do
virsh start $x;
done
$ echo {{foo,bar}} {{baz,boz}}
foo baz
foo boz
bar baz
bar boz
$ for x in foo bar; do
> for y in baz boz; do
> echo $x $y
> done
> done
foo baz
foo boz
bar baz
bar boz
Yo Dawg! I heard you like arrays, so we put some arrays in your arrays...
No but seriously...
In JSON you can nest an array inside an element of an array.
Is this even possible in BASH?
Let's say I have a 2D array.
My2DArray[0,0\] - My2DArray[8,8\]
Can I place an array inside one location of that matrix? Say: My2DArray[4,3\]=(5 7 8 9)?
I am asking for a friend, but before I try it, and the fabric of the universe implodes on itself and reality ceases to follow the laws of Quantum Dynamics.
PS: I am a coder with high levels of anxiety. So I have no friends. Therefore I am asking for myself.
https://redd.it/16qcwf2
@r_bash
optParse: an options-parsing tool that makes parsing options easy, efficient, and fast to implement
The [CODE](https://github.com/jkool702/forkrun/blob/main/optParse.bash) and a [USAGE EXAMPLE + SPEEDTEST](https://github.com/jkool702/forkrun/blob/main/optParse_test.bash) is hosted on github.
This is a follow-up/continuation to [this](https://www.reddit.com/r/bash/comments/16lpgps/rparse_an_easytouse_shell_scriptfunction_option/) post about [rparse](https://github.com/jkool702/forkrun/blob/main/rparse.bash), which does regex-based option parsing.
`optParse` is a tool that takes a simple "option parsing definition table" that you define and expands it into a full option parsing function that uses a robust and very efficient "loop over options and run each through a `case` statement" approach. Options are defined using `case` statement syntax (either standard or ext-glob-based).
The "option parsing definition table" is a table containing a lines of the following syntax (1 line per option you want to parse):
<CASE_MATCHES> :: <VAR_TO_ASSIGN> <CMDS_TO_RUN>
NOTES:
* For options without arguments, set `<VAR_TO_ASSIGN>` to `-`
* For options with arguments, they may be passed via with a (space), with an `=`, or with nothing seperating the option and the argument. i.e., `-o $arg` or `--opt $arg` or '-o=$arg' or `--opt=$arg` or `-o$arg` or `--opt$arg` all work.
* Options must begin with a `-` or `+`, but are otherwise matched without restriction.
* when passing options to the function/script you are developing, options must be given before any non-option arguments, and passing `--` will stop further inputs from being treated as options.
* Any non-option arguments are saved in a bash array `inFun`
***
EXAMPLE:
source <(genOptParse<<'EOF'
-a --apple :: - flag_a=true
-b --bananna :: var_b
-c --coconut :: var_c flag_c=true
EOF
)
optParse "$@"
The above will generate the following code, which is generates and sources the following optParse function which will parse options for you (run `optParse "$@"`). Note that instead of wrapping things in a `source <(...)` statement, it is more efficient to generate the `optParse` function and copy/paste it directly into the code. However, if the code is in development and options are changing frequently using `source <(...)` is easier to maintain.
declare -a inFun
inFun=()
shopt -s extglob
unset optParse
optParse() {
local continueFlag
continueFlag=true
while ${continueFlag} && (( $# > 0 )) && [[ "$1" == [\-\+]* ]]; do
case "${1}" in
-a|--apple)
shift 1
flag_a=true
;;
-b|--bananna)
var_b="${2}"
shift 2
;;
-b?(=)+([[:graph:]])|--bananna?(=)+([[:graph:]]))
var_b="${1##@(-b?(=)|--bananna?(=))}"
shift 1
;;
-c|--coconut)
var_c="${2}"
shift 2
flag_c=true
;;
-c?(=)+([[:graph:]])|--coconut?(=)+([[:graph:]]))
var_c="${1##@(-c?(=)|--coconut?(=))}"
shift 1
flag_c=true
;;
'--')
shift 1
continueFlag=false
break
;;
@([\-\+])*)
printf '\nWARNING: FLAG "%s" NOT RECOGNIZED. IGNORING.\n\n' "$1"
shift 1
;;
*)
continueFlag=false
break
;;
esac
[[ $# == 0 ]] && continueFlag=false
done
inFun=("${@}")
}
***
There is additionally an optional pre-parser function that will find any option definitions that
1. have no argument, and
2. only serve so set 1+ "flag" variables to
Why can't OpenVPN take pass input in a bash cript?
So I have would like to have a script like this:
#!/usr/bin/env bash
sudo openvpn --config path/to/my/conf --auth-user-pass "$(pass show openvpn/passwd)"
Doesn't work though:
$ bash my-openvpn-script.sh
2023-09-22 13:54:41 Cannot pre-load keyfile (the-key-file-here)
2023-09-22 13:54:41 Exiting due to fatal error
In my mind it should work since the output is the same as a file would be:
$ cat filewithpasswd.txt
username
the-passwd
$ pass show openvpn/passwd
username
the-passwd
It only works if I feed the filewithpasswd.txt instead of with pass-command. Somehow a file and output displayed in pass is different somehow? How can pass be used with openvpn in a bash script?
https://redd.it/16p7826
@r_bash
fastest way to temporary corrupt a video file
Hello everyone, I'm thing to back up my videos files from my laptop HDD into portable SSD,
my concerns it could be opened by someone else intentionally or by accident
I know that most of the video file information are stored in it header (the beginning)
So I was thinking about adding any garbage data into it, so the video player won't recognize it format ..
I'm thinking using dd
command in a Bach script, but I don't want to wipe out any of my partition by accident
I want this command to reversible so I can reopen these files again .
BTW I don't to encrypt the files, just add extra data to it header so video play won't recognize it, that enough for me
https://redd.it/16owqut
@r_bash
overthinking it to script exporting keys from /etc/apt/trusted.gpg to /etc/apt/trusted.gpg.d
I like to automate the installation of programs as much as I can. In my stable of shell scripts I have ones like i-ghostscript-from-source.sh, i-github-cli.sh, and i-apache2.sh that build or install the program and set up basic configuration.
As it happens, I needed to install google-chrome-stable
, so I followed some instructions I found online, and one of the first steps is to obtain Google's signing keys so I can add the Chrome repo as an apt
source. While adding Google's keys using apt-key
, I got this warning:
Key is stored in legacy trusted.gpg keyring (/etc/apt/trusted.gpg), see the DEPRECATION section in apt-key(8) for details.
So I modified my install script to export the keys from trusted.gpg to trusted.gpg.d to avoid the warning. My question for /r/bash has to do with the way I went about this. Basically I saved a copy of my keys before adding the Google keys, and then I saved a copy of my keys after. Then I diff
ed the two key listings to extract Google's keys and put them in a bash array for exporting. Did I totally overengineer/overthink this? Or this is a semi-legit strategy for this situation? Script below, and all critique or suggestions welcome.
#!/usr/bin/env bash
# debugging switches
# set -o errexit # abort on nonzero exit status; same as set -e
# set -o nounset # abort on unbound variable; same as set -u
# set -o pipefail # don't hide errors within pipes
# set -o xtrace # show commands being executed; same as set -x
# set -o verbose # verbose mode; same as set -v
source ./functions.sh # for die-if-not-root
die-if-not-root
TMP=$(mktemp -d)
# save a copy of my keys before downloading Google's keys
apt-key list > "$TMP/before.txt"
# get the Google keys and add them using apt-key
wget -q -O - https://dl-ssl.google.com/linux/linuxsigningkey.pub | apt-key add -
# save a copy of the keys, including Google's
apt-key list > "$TMP/after.txt"
# populate an array with the last 8 digits of the new keys that were added
readarray -t newkeysuffixes < <(diff "$TMP/before.txt" "$TMP/after.txt" | grep -o -E "0-9A-F{4}\ +0-9A-F{4}$" | awk '{print $1 $2}')
# iterate those key suffixes and put them in trusted.gpg.d
for eachkeysuffix in "${newkeysuffixes@}"; do
apt-key export "${eachkeysuffix}" | gpg --dearmour -o "/etc/apt/trusted.gpg.d/google-${eachkeysuffix}.gpg"
done
# add Google's repo
bash -c 'echo "deb arch=amd64 http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
# finally, install google-chrome-stable
apt-get -y update
apt-get -y install google-chrome-stable
https://redd.it/16o7rzj
@r_bash
How did you made this incredible banners.... in your scripts
Hello guys I was thinking how the hell is possible to make incredible banners like this and what would you recommend me to be a pro in scripting(bash) ? I like to learn by books and videos.
https://preview.redd.it/69qmvubiajpb1.png?width=1030&format=png&auto=webp&s=5884d84e5461069031fb4be748771358c1ad22bf
https://preview.redd.it/0iuk8hhdajpb1.png?width=544&format=png&auto=webp&s=4b2c04debab9cdb9428d6281287db8ed7aa2b5a0
https://redd.it/16o61qm
@r_bash
Give value tp variable through ssh from windows
There are any solution to give values to variable through ssh? i echo the variable to check its blank
ssh user@remoteip "
backuppath=/some/path
read -p 'Do you really want to delete backups [Y/n\] ' Answer;
if [ $answer ==Y \]; then
find $backuppath -type d -name ""BKP_*"" -exec rm -rf {} \\;
echo "backups deleted"
else
echo ""ERRO""
"
There are any solotion to give values to variable through ssh?
Thanks in advance.
https://redd.it/16nr13u
@r_bash
Working with fzf - The Command-Line Fuzzy Finder
https://muhammadraza.me/2023/fzf/
https://redd.it/16nkjz7
@r_bash
Question about read command
I need my read loop to break when it hits an empty line. I was suggested to use this command, but I am confused why the "-z $line" conditional is true when there is an empty line?
while IFS= read -r line; do
if [ -z $line ]; then
break
​
https://redd.it/16nbzro
@r_bash
getopts "require" flag (or running script with no flags just shows usage)
Hey all,
I've got a generic script that I'd like to *require* a/any flag in order for it do anything, and if no flag is included (i.e. just running ./foo.sh) outputs the usage function.
​
So:
running ./foo.sh
outputs via 'echo' ./foo.sh [ -s \] to do bar, ./foo.sh [ -d \] to do foobar
running ./foo.sh -s
does foo
running ./foo.sh -d
does foobar
​
Note: none of the flags require any arguments. The flags alone is all that's needed
​
Full getopts part of function will be in a comment so as to not fill the OP
https://redd.it/16n07lb
@r_bash
Use curl to download from password protected host
I'm writing a bash script which takes in a url as argument and prompts username and password inputs in order to download the file from the url. The problem is curl wants to know the target file name (which is at the end of the url) in order to download. I imagine a solution involving regex to match the end of the url to a pattern. Is there a better way to implement this ?
https://redd.it/16m4nsk
@r_bash
rparse: an easy-to-use shell script/function option parser that uses regex to determine which inputs are optionsrparse
makes it very easy to define options (inputs that start with a dash (-
)) using extended regex matching. Using regex makes it possible to define many options in a single short string, and allow for a degree of "fuzzy" option matching, should you desire it. These regex option definitions and what is triggered by said options is added into an "option definition table" and passed to rparse
(via stdin) along with the commandline you want parsed (via function input). rparse
will take this info and return a list of commands to run based on the options that were present.
Lines in the option definition table use 1 of 2 possible syntaxes, depending on if that option has an argument associated with it.
Options without arguments use the format:
<REGEX> -> <CMDS>
For every input option that matches the <REGEX> definition, the command(s) listed in <CMDS> will run.
Options with arguments use the format:
<REGEX> => <VAR>
For every input option that matches the <REGEX> definition, the variable <VAR> will be set as the argument given along with the option.
Example
Aa? -> ((applecount++))
b(anannas?)? => banannaVar
This will:
make any of `-a` `-A` `--apple` `--Apple` `--apples` `--Apples` increment the variable `applecount` by 1
make any of -b <...>
--bananna <...>
--banannas <...>
-b=<...>
--bananna=<...>
--banannas=<...>
result in settting banannaVar=<...>
Ok, here is the code, along with a functioning simple example of using rparse
. Let me know what you think!
rparse() {
## Extended-Regex sed-based options parser for bash shell functions and scripts
#
# Define options in table. Lines of the table can have one of 2 formats:
# <REGEX> -> <CMD> ( for options without arguments. <CMD> will be run when option is read. )
# <REGEX> => <VAR> ( for options with arguments. Variable <VAR> will be set to the argument. )
#
# NOTE: Do not include the leading dash ('-') in table. Options can have any number (1+) of leading dashes.
#
# Pass the option definition table on stdin. Pass the cmdline you want to parse as function input.
# rparse
will output the commands that you want to run. source the output to actually run them.
local -a sedfilt0 ii
local -i nkk kk
nkk=0
ii=("${@}")
# transform options table into a sed filter for cmdline to parse
{
mapfile -t sedfilt0 < <(cat <&${fd0} | grep -E '.+' | sed -E 's/^(.) -> (.)$/s\/^-+\1( ^-.)? $\/\2\/; /; s/^(.) => (.) $/s\/^-+\1[= ]\/\2=\/;/')
} {fd0}<&0
# break up options into 1 per line and then run it through the sed filter we just made
# for options with arguments, keep the argument on the same line as its corresponding option
{
for kk in ${!ii[@]}; do
case "${ii[$kk]}" in
'--')
break;
;;
'-'=)
printf '\n%s ' "${ii[$kk]%%=} ${ii$kk#=}"
nkk=2
;;
-)
printf '\n%s ' "${ii$kk}"
nkk=1
;;
)
{ (( $nkk == 0 )) || (( $nkk >= 2 )); } && break
printf '%s ' "${ii[$kk]}"
((nkk++))
;;
esac
done
printf '\n'
} | sed -E "${sedfilt0[]}"
}
# define testing function
gg() {
local sedfilt flagA valB
flagA=false
# define options table
# if option '-a' or '--apple' is given, the command flagA=true
is run
# if '-b <...>' or '--bananna <...>' or '--bananna=<...>' is given, set variable "valB" to <...> (i.e., run
Introduction to bash
Hello Bash community, I come from a hellish landscape that is Windows 11 + Batch. I am going to be taking a Unix/Linux class at my CC as part of my IT Sysadmin degree, and I am curious to know if there are any good YouTube playlists or free courses that offer a "ground zero" introduction to bash and bash scripting? When I see bash scripts, they look quite unfamiliar, and I am sure that there are also oddities in the language as there are in CMD. I have never found myself able to understand regexes much, though I hear this is commonly used in Bash.
https://redd.it/16ri1oi
@r_bash
POLL: You're on a strangers computer, typing into terminal. You don't know what terminal/settings/OS but it's probably defaults. You see a b that should be a p. You click your mouse on the b and nothing happens. What's your next moves? (Please don't say "backspace x 19")
https://redd.it/16qgrp8
@r_bash
`true`
and will automatically generate+add an analogous `+option` to the option parsing definition table that sets these variable(s) to false instead. in the above example, had we used
source <({ genOptParse_pre | genOptParse; }<<'EOF'
The pre-parser would have added
+a ++apple :: - flag_a=false
to the option parsing definition table; which in turn would have added
+a|++apple)
shift 1
flag_a=false
;;
as an additional `case` match in the `optParse` function.
Comments? Suggestions? Bugs? Let me know. Hope some of you find this useful.
https://redd.it/16q89py
@r_bash
Hi everybody, I am sharing my YDF Package Directory setup
https://github.com/yunielrc/.ydf-packages
https://redd.it/16plja7
@r_bash
A disruptive dotfiles manager and more, Full written in bash
https://github.com/yunielrc/ydf
https://redd.it/16owdg4
@r_bash
Help making my loop faster
I have a text file with about 600k lines, each one a full path to a file. I need to move each of the files to a different location. I created the following loop to grep through each line. If the filename has "_string" in it, I need to move it to a certain directory, otherwise move it to a different certain directory.
For example, here are two lines I might find in the 600k file:
1. /path/to/file/foo/bar/blah/filename12345.txt
2. /path/to/file/bar/foo/blah/file_string12345.txt
The first file does not have "_string" in its name (or path, technically) so it would move to dest1 below (/new/location/foo/bar/filename12345.txt)
The second file does have "_string" in its name (or path) so it would move to dest2 below (/new/location/bar/foo/file_string12345.txt)
while read -r line; do
var1=$(echo "$line" | cut -d/ -f5)
var2=$(echo "$line" | cut -d/ -f6)
dest1="/new/location1/$var1/$var2/"
dest2="/new/location2/$var1/$var2/"
if LCALL=C grep -F -q "string" <<< "$line"; then
echo -e "mkdir -p '$dest1'\nmv '$line' '$dest1'\nln --relative --symbolic '$dest1/$(basename $line)' '$line'" >> stringFiles.txt
else
echo -e "mkdir -p '$dest2'\nmv '$line' '$dest2'\nln --relative --symbolic '$dest2/$(basename $line)' '$line'" >> nostringFiles.txt
fi
done < /path/to/600kFile
I've tried to improve the speed by adding LC_ALL=C
and the -F
to the grep command, but running this loop takes over an hour. If it's not obvious, I'm not actually moving the files at this point, I am just creating a file with a mkdir command, a mv command, and a symlink command (all to be executed later).
So, my question is: Is this loop taking so long because its looping through 600k times, or because it's writing out to a file 600k times? Or both?
Either way, is there any way to make it faster?
\--Edit--
The script works, ignore any typos I may have made transcribing it into this post.
https://redd.it/16oh5j7
@r_bash
Here is ydf written in full BASH, The disruptive dotfiles manager+
https://github.com/yunielrc/ydf
https://redd.it/16o5sla
@r_bash
bash script help
Hello everyone,
I am trying to do this bash script that allows me to choose between .conf files in /etc/wireguard and at the end of it will execute wg-quick ... it is giving me configuration not found, the files exist...can someone tell me where I am failing please..much appreciated. Thank you.
#!/bin/bash
# Directory where WireGuard configuration files are stored
CONFIG_DIR="/etc/wireguard"
# List all files in the configuration directory
config_files=("gb-mnc-wg-007.conf" "pt-lis-wg-102.conf")
# Prompt user to choose a configuration file
echo "Available WireGuard configuration files:"
for ((i=0; i<${#config_files[@]}; i++)); do
echo "[$i] $(basename "${config_files[i]}")"
done
read -p "Enter the number of the configuration file you want to execute: " choice
# Validate user input
if [[ ! "$choice" =~ ^[0-9]+$ ]] || ((choice < 0)) || ((choice >= ${#config_files[@]})); then
echo "Invalid choice. Please enter a valid number."
exit 1
fi
# Get the chosen configuration file
selected_config="${config_files[choice]}"
# Execute WireGuard with the chosen configuration
if [[ -f "$selected_config" ]]; then
sudo wg-quick up "$CONFIG_DIR/$selected_config"
echo "WireGuard configuration '$selected_config' has been activated."
else
echo "Configuration file not found."
exit 1
fi
​
https://redd.it/16nyb0n
@r_bash
Can get env when run the script via SSH
// Look at the picture first in case TLDR
I have a script like this:
deploy_test_env.sh
#!/bin/bash
echo $ENVVAR
$ENV\VAR is an env variable on the host I want to run deploy_test_env.sh.
When I try to run this script normally, it works fine.
But when I run it by pipe it into ssh like this:
\-ssh $SSH_USERNAME@$SSH_HOSTNAME 'bash -s' < ./deploy_test_env.sh
The output is nothing.
I have edited the \~/.bashrc on the remote host also.
​
https://preview.redd.it/sthy0zxxlfpb1.png?width=1152&format=png&auto=webp&s=f2284c7ed235f205a097e65a3ef94177d3550094
https://redd.it/16nonv2
@r_bash
Here is VEDV written in pure BASH, A tool for developing applications with virtual machines using a Docker-like workflow.
The software we are developing needs to be tested on a system as closed as possible to the one where it is going to be executed. Sometimes it is very difficult to satisfy this requirement with docker and we have to use virtual machines missing the docker workflow. This is why I started the development of vedv. I hope you find it useful. Thank you.
https://github.com/yunielrc/vedv
​
https://redd.it/16mvdnf
@r_bash
Format Bash Command – apply indentation and line breaks
https://ray.run/tools/bash-command-formatter
https://redd.it/16n234s
@r_bash
Changing audio output with scripts
Hello,
I want to make a script that changes my audio outputs if I run it
​
The problem is that my setup is a bit weird
I have 2 cards
​
alsa_card.usb-Corsair_CORSAIR_VIRTUOSO_Wireless_Gaming_Headset_16adc305000000da-00
​
​
alsa_card.pci-0000_01_00.1
​
​
And with this there would be no problems, but I have problems with the fact that under the pci card I have two profiles, output:hdmi-stereo-extra1 and output:hdmi-stereo-extra2 one is my TV the other is my monitorAnd also I would need to disable all other cards/profiles so new and existing audio is forced on the newly set output
​
I tried searching google for solutions but most either causes my audio to not even work, or because of the profile settings does not want to go from Headphones into TV and things like this
​
Any help would be nice
EDIT: I would need to do this in 3 separate scripts, since I have 3 outputs I want to use
https://redd.it/16mw7sl
@r_bash
valB=<...>
)
sedfilt="$(cat<<'EOF'
a(pple)? -> flagA=true
b(anannas?)? => valB
EOF
)"
# pass rparse the option table on its stdin and the commandline as function inputs, then source its output
source <({ rparse "$@"; }<<<"${sedfilt}")
# check things were set correctly
echo "flagA = ${flagA}"
echo "valB = ${valB}"
# do stuff probably
}
# try it out
gg
gg -a
gg -apple
gg -b 0
gg --bananna=1
gg -a --bananna=2
gg -b 3 --apple --bananna 4
gg -a --bananna 4 -b 3 --apple -bananna=2 -a -b=1 func arg nonoption
https://redd.it/16lpgps
@r_bash
How to setup commitlint, auto format all bash files and auto shellcheck all bash files for a BASH only project in VSCode?
​
https://preview.redd.it/ka0g8jqhljob1.png?width=628&format=png&auto=webp&s=1d45e3aaea29a71404c3237f2a1e0e273a386f0c
I have a project on VSCode with nothing but a bunch of bash scripts
I would like to be able to verify the commit messages to match conventional commit format everytime I want to commit something to git
I would also like to auto format all files on commit and auto shellcheck all files on commit or should I say that commit should fail if shellcheck has problems
How do I set something like this up on VSCode?
https://redd.it/16jxw0l
@r_bash