social nets from bash lynx
m.facebook.com worked for me in 2021. gmail stopped working early 2021 because of javanoscript, tho had used html mode a decade. a coupla years ago linkedin kept trying to catchpa me but despite scp failed. have seen bash noscripts for twitter and reddit but never worked. anyone care to give a general status report with urls?
https://redd.it/z5jr1y
@r_bash
m.facebook.com worked for me in 2021. gmail stopped working early 2021 because of javanoscript, tho had used html mode a decade. a coupla years ago linkedin kept trying to catchpa me but despite scp failed. have seen bash noscripts for twitter and reddit but never worked. anyone care to give a general status report with urls?
https://redd.it/z5jr1y
@r_bash
reddit
social nets from bash lynx
m.facebook.com worked for me in 2021. gmail stopped working early 2021 because of javanoscript, tho had used html mode a decade. a coupla years ago...
Pulling information about processes from /proc/pid/stat
Hi, I need to display information about all running processes (pid, ppid) from /proc/pid/stat. Any tips how to get around this?
https://redd.it/z5yxu4
@r_bash
Hi, I need to display information about all running processes (pid, ppid) from /proc/pid/stat. Any tips how to get around this?
https://redd.it/z5yxu4
@r_bash
reddit
Pulling information about processes from /proc/pid/stat
Hi, I need to display information about all running processes (pid, ppid) from /proc/pid/stat. Any tips how to get around this?
How to log bash commands in some simple way?
I would like to log bash commands to a log file. Seems easy enough, but i have searched and searched and not found a simple and sufficient method.
It seems like this should be possible by hooking in to some bash function/variable, but there is always something missing:/
I tried enhancing the history a bit here https://www.reddit.com/r/bash/comments/z583sh/no\_way\_to\_record\_pwd\_in\_the\_bash\_history\_i\_guess but that failed.
Sorry for that untested post by the way.
The utility "noscript" almost seems good enough, but for some reason there is no way to get a timestamp for each command!? (or is there?)
(i have seen solutions where the output of noscript is piped through for instance 'ts', but i would really like to avoid too many sub-processes and pipes and stuff, that will just cause problems later on).
I saw one solution where PROMPT_COMMAND was used together with "history | tail -n", but that wont work when commands take long to complete. The timestamp will be when the command finished...
Basically i would like to log like this
>2022-11-27 12:00 [user\] [env-var\] [cwd\] the command...
Where 'env-var' could be any variable from the environment.
Is there really no way to just get bash to execute some function that gets the input passed as arguments each time a command is executed?
Sorry for posting yet another of these questions. I have found many many questions kinda like this, but really strangely enough no simple and satisfactory solutions.
https://redd.it/z6119l
@r_bash
I would like to log bash commands to a log file. Seems easy enough, but i have searched and searched and not found a simple and sufficient method.
It seems like this should be possible by hooking in to some bash function/variable, but there is always something missing:/
I tried enhancing the history a bit here https://www.reddit.com/r/bash/comments/z583sh/no\_way\_to\_record\_pwd\_in\_the\_bash\_history\_i\_guess but that failed.
Sorry for that untested post by the way.
The utility "noscript" almost seems good enough, but for some reason there is no way to get a timestamp for each command!? (or is there?)
(i have seen solutions where the output of noscript is piped through for instance 'ts', but i would really like to avoid too many sub-processes and pipes and stuff, that will just cause problems later on).
I saw one solution where PROMPT_COMMAND was used together with "history | tail -n", but that wont work when commands take long to complete. The timestamp will be when the command finished...
Basically i would like to log like this
>2022-11-27 12:00 [user\] [env-var\] [cwd\] the command...
Where 'env-var' could be any variable from the environment.
Is there really no way to just get bash to execute some function that gets the input passed as arguments each time a command is executed?
Sorry for posting yet another of these questions. I have found many many questions kinda like this, but really strangely enough no simple and satisfactory solutions.
https://redd.it/z6119l
@r_bash
reddit
no way to record PWD in the bash history i guess?
I want a better history, and did this export HISTTIMEFORMAT="%F_%H:%M:%S [$ssh_key_comment] " $ssh\_key\_comment is figured out in a...
any help for a noob learning his first noscripts? im trying to make them funny and functional
This all just fun between friends, my friend Lucy is interested in learning Linux like me, and make the joke that she'll always be a root vegetable not a root user. I even had help making another noscript which randomly decides which random yet amusingly shaped root vegetable she is today. She loves it. I'm working on another, and obviously I thought i put it together well enough, but I'm obviously just more confident than I am skilled, but that's how we learn right by trying stuff. Anyway here's my code if someone could make it work id study from it for days re-writing different but similar ones to check if my new-found instincts are right. But if someone could just give me general hints that'd be good too, i want to learn anyway I can.
\#!/bin/bash
echo "Thanks to traversery media"
sleep 3
read -p "what is your name?" NAME
if [ "$NAME" \] == lucy or == Lucy
then read -p "are you a potato?"
if $INPUT1 echo "$ANSWER1"
else
if $INPUT2 read -p you another root vegetable?
if $INPUT1 then echo "$ANSWER1" if $INPUT2 echo "$ANSWER3"
INPUT1 yes
INPUT2 no
\#ANSWER2 read -p are you another root vegetable?
ANSWER1 "Your ok then, your names on the root list you may enter"
ANSWER3 "fatal logical error does not compute according to my database all known
lucys are root vegetables not root fatal error forcing shutdown"
else echo "$ANSWER1"
fi
https://redd.it/z64iuf
@r_bash
This all just fun between friends, my friend Lucy is interested in learning Linux like me, and make the joke that she'll always be a root vegetable not a root user. I even had help making another noscript which randomly decides which random yet amusingly shaped root vegetable she is today. She loves it. I'm working on another, and obviously I thought i put it together well enough, but I'm obviously just more confident than I am skilled, but that's how we learn right by trying stuff. Anyway here's my code if someone could make it work id study from it for days re-writing different but similar ones to check if my new-found instincts are right. But if someone could just give me general hints that'd be good too, i want to learn anyway I can.
\#!/bin/bash
echo "Thanks to traversery media"
sleep 3
read -p "what is your name?" NAME
if [ "$NAME" \] == lucy or == Lucy
then read -p "are you a potato?"
if $INPUT1 echo "$ANSWER1"
else
if $INPUT2 read -p you another root vegetable?
if $INPUT1 then echo "$ANSWER1" if $INPUT2 echo "$ANSWER3"
INPUT1 yes
INPUT2 no
\#ANSWER2 read -p are you another root vegetable?
ANSWER1 "Your ok then, your names on the root list you may enter"
ANSWER3 "fatal logical error does not compute according to my database all known
lucys are root vegetables not root fatal error forcing shutdown"
else echo "$ANSWER1"
fi
https://redd.it/z64iuf
@r_bash
reddit
any help for a noob learning his first noscripts? im trying to make...
This all just fun between friends, my friend Lucy is interested in learning Linux like me, and make the joke that she'll always be a root...
Scraping weather info
Hi, I’m trying to scrape some weather information using sed and grep from: https://api.met.no/weatherapi/locationforecast/2.0/classic\?lat\=60.795\&lon\=10.691
What I’m trying to do is:
1. extract the temperature forecast for the current hour, the next hour and the hour after that.
2. extract the next precipitation forecast.
3. the date and time when the meteorological data has been scraped.
Example of how I want the output to look (I want them “stacked”/under each other, but couldn’t format that):
3
0
-4
Cloudy
2022-11-24 10:03
What I know is that I probably should grep something, but not sure what and how
curl -s https://api.met.no/weatherapi/locationforecast/2.0/classic\?lat\=60.795\&lon\=10.691 | grep
I have found these commands that I think could be useful, but I don’t know how to use them in this case.
grep -Eo "0-9{2}:0-9{2}:0-9{2}"
date +"%Y-%m-%d"
date +"%Y-%m-%d %H:%M"
https://redd.it/z3f73f
@r_bash
Hi, I’m trying to scrape some weather information using sed and grep from: https://api.met.no/weatherapi/locationforecast/2.0/classic\?lat\=60.795\&lon\=10.691
What I’m trying to do is:
1. extract the temperature forecast for the current hour, the next hour and the hour after that.
2. extract the next precipitation forecast.
3. the date and time when the meteorological data has been scraped.
Example of how I want the output to look (I want them “stacked”/under each other, but couldn’t format that):
3
0
-4
Cloudy
2022-11-24 10:03
What I know is that I probably should grep something, but not sure what and how
curl -s https://api.met.no/weatherapi/locationforecast/2.0/classic\?lat\=60.795\&lon\=10.691 | grep
I have found these commands that I think could be useful, but I don’t know how to use them in this case.
grep -Eo "0-9{2}:0-9{2}:0-9{2}"
date +"%Y-%m-%d"
date +"%Y-%m-%d %H:%M"
https://redd.it/z3f73f
@r_bash
Is there something like w3school but for bash? or any other shell?
I'm looking for an online resource for learning shell noscripting. I dont really find youtube lessons helpful so written material works better for me. Books could also work tbh but no video plz :D
https://redd.it/z68zbh
@r_bash
I'm looking for an online resource for learning shell noscripting. I dont really find youtube lessons helpful so written material works better for me. Books could also work tbh but no video plz :D
https://redd.it/z68zbh
@r_bash
reddit
Is there something like w3school but for bash? or any other shell?
I'm looking for an online resource for learning shell noscripting. I dont really find youtube lessons helpful so written material works better for...
I'm currently taking a Google Cloud Course that includes Qwiklabs. I've been tasked with translating one of the labs into a linux bash noscript. I've done that but i'd like someone who knows what they're doing to take a look at it before i turn it in. I'd really appreciate it. Thanks in anticipation.
I'm currently a big noob trying to wrap my head around tech. please be nice
https://redd.it/z6ala6
@r_bash
I'm currently a big noob trying to wrap my head around tech. please be nice
https://redd.it/z6ala6
@r_bash
reddit
I'm currently taking a Google Cloud Course that includes Qwiklabs....
I'm currently a big noob trying to wrap my head around tech. please be nice
What does this noscript do? I need to explain what this noscript does for a question on my classwork but my teacher isn't satisfied with my answer. Can anyone provide some insight into what exactly is happening with this noscript?
https://redd.it/z6c7x0
@r_bash
https://redd.it/z6c7x0
@r_bash
Getopts to allow only 1 option
How can I make getopts to allow only one option?
while getopts ":ab" option
do
case $option in
a)
echo "test1"
;;
b)
echo "test2"
;;
esac
done
This is an example loop, running the noscript
./noscript.sh -a -b
will return both a and b cases. How can I make it to show an error message instead?
https://redd.it/z6hq3c
@r_bash
How can I make getopts to allow only one option?
while getopts ":ab" option
do
case $option in
a)
echo "test1"
;;
b)
echo "test2"
;;
esac
done
This is an example loop, running the noscript
./noscript.sh -a -b
will return both a and b cases. How can I make it to show an error message instead?
https://redd.it/z6hq3c
@r_bash
reddit
Getopts to allow only 1 option
How can I make getopts to allow only one option? while getopts ":ab" option do case $option in a) echo...
printf with colour using variable
I thought i was being clever using printf with colour variables to save me typing out the colour i'd like, but apparently shellcheck doesn't like that
for instance...
red="\e1;31m%s\e[0m\n"
green="\e[1;32m%s\e[0m\n"
yellow="\e[1;33m%s\e[0m\n"
and then
printf "$red" "string of sorts in red colour"
Since it complains, is there another way, or just suppress and ignore it (i've been ignoring it up until now since i discovered shellcheck, and never run into any problems)? Thought i'd ask just in case it does fluff something up i'm unaware of.
[https://redd.it/z6vhvv
@r_bash
I thought i was being clever using printf with colour variables to save me typing out the colour i'd like, but apparently shellcheck doesn't like that
for instance...
red="\e1;31m%s\e[0m\n"
green="\e[1;32m%s\e[0m\n"
yellow="\e[1;33m%s\e[0m\n"
and then
printf "$red" "string of sorts in red colour"
Since it complains, is there another way, or just suppress and ignore it (i've been ignoring it up until now since i discovered shellcheck, and never run into any problems)? Thought i'd ask just in case it does fluff something up i'm unaware of.
[https://redd.it/z6vhvv
@r_bash
reddit
printf with colour using variable
I thought i was being clever using printf with colour variables to save me typing out the colour i'd like, but apparently shellcheck doesn't like...
eval vs sourceI recently discovered that you can get functionality similar to
eval ... with source <(...). There is some difference in functionality - mostly that
eval can be used within some code statement whereas source <(...) requires complete statements. e.g. in someFunction $(eval $someCode) the eval ... cant be replaced with source <(...). The flip side of this is that source <(...) will evaluate everything between the paranthesies, whereas eval will stop evaluating at pipes/newlines/semicolons. Any other considerations regarding these two that are worth knowing?
Side note: I'm not advocating using these for "general noscripting", but there are some situations where they are useful. Examples of what Id call "reasonable usage" for both are:
eval ...
for nn in $(eval echo {$start..$end..$skip}); do
<...>
done
Yes, I know you can do
nn=$start
while [ $nn -le $end]; do
<...>
nn=$((( $nn + $skip )))
done
but its just an example
source <(...)
# passing an array to a noscript
declare -p arrayName | noscript.sh
# in noscript.sh
source <(cat)
https://redd.it/z6wm7f
@r_bash
reddit
`eval` vs `source`
I recently discovered that you can get functionality similar to `eval ...` with `source <(...)`. There is some difference in functionality -...
New to Bash
Hey everyone...
I'm super new to bash noscripting, I'm working through a class currently and I am stuck. I need help, I'm trying to isolate a particular word and print out the results.
Would I be using awk then pipe and wc? For example, this particular scenario involves searching for individuals who are creating a loss of profit. I need to isolate the people responsible and print it to a new evidence file. I think I just don't have enough practice to understand it yet, any help would be appreciated! If you are curious and want to see the exact code DM me for it.
https://redd.it/z6zq0g
@r_bash
Hey everyone...
I'm super new to bash noscripting, I'm working through a class currently and I am stuck. I need help, I'm trying to isolate a particular word and print out the results.
Would I be using awk then pipe and wc? For example, this particular scenario involves searching for individuals who are creating a loss of profit. I need to isolate the people responsible and print it to a new evidence file. I think I just don't have enough practice to understand it yet, any help would be appreciated! If you are curious and want to see the exact code DM me for it.
https://redd.it/z6zq0g
@r_bash
reddit
New to Bash
Hey everyone... I'm super new to bash noscripting, I'm working through a class currently and I am stuck. I need help, I'm trying to isolate a...
This is my first bash noscript! What do you think? You plug in your droplet ip, your domain and your gitlab info and in 5 minutes your web app is live at https://yourdomain, and all future commits to main are automatically deployed. Included templates for new django, flask and fastApi projects!
https://github.com/johnsyncs/ezinnit
https://redd.it/z74xq9
@r_bash
https://github.com/johnsyncs/ezinnit
https://redd.it/z74xq9
@r_bash
GitHub
GitHub - johnsyncs/ezinnit: ezinnit initializes your gitlab repository and your server. Your app will be live and commits to main…
ezinnit initializes your gitlab repository and your server. Your app will be live and commits to main will automatically deploy. - GitHub - johnsyncs/ezinnit: ezinnit initializes your gitlab reposi...
hfetch, a simple and minimal system information tool written in bash. with fortune
https://redd.it/z776ux
@r_bash
https://redd.it/z776ux
@r_bash
associative array order
I've noticed, while playing around with associative arrays, that when I append keys/values, the appended pairs stay in the order I added them in stdout, unlike the key/value pairs I declared the array with. If that's the case, can I take advantage of that in order to control the way associative arrays are displayed?
https://redd.it/z7bcmb
@r_bash
I've noticed, while playing around with associative arrays, that when I append keys/values, the appended pairs stay in the order I added them in stdout, unlike the key/value pairs I declared the array with. If that's the case, can I take advantage of that in order to control the way associative arrays are displayed?
https://redd.it/z7bcmb
@r_bash
reddit
associative array order
I've noticed, while playing around with associative arrays, that when I append keys/values, the appended pairs stay in the order I added them in...
Script to detect change in URL redirection:
I've been hesitant to submit this in fear that I have re-invented the wheel here, but please tell me if I have.
#!/usr/bin/env bash
# Script to be placed in /etc/cron.d/cron.hourly
###############################################################################################################
# Ignore below comment, it's just for shellcheck. (Must appear before any instructions.) #
# shellcheck disable=SC1090 # Can't follow non-constant source #
# shellcheck disable=SC2034 # Yea, I have some unused variables #
###############################################################################################################
requiredPackages=(
alsa-utils
coreutils
curl
wc
wget
zenity
)
noscriptBasename=$(basename "${0}") # Could also user ${BASH_SOURCE[0]} here.
kibibyte="1024"
mebibyte="$(( kibibyte * kibibyte ))"
###############################################################################################################
########################################### Configuration Variables: ##########################################
###############################################################################################################
### Inputs: Wikipedia example ######################################################################################
user="user"
workingDir="/home/${user}/${noscriptBasename}"
audioOutputDevice="plughw:CARD=NVidia,DEV=3" # Get list of available devices with: aplay -L | grep "CARD"
maxLogSize="$((1 * mebibyte))" #bytes
notificationSound="${workingDir}/notify.wav"
urlToWatch="https://en.wikipedia.org/wiki/Redirect_page" # Will redirect to https://en.wikipedia.org/wiki/URL_redirection
notificatonTitle="Redirect change"
notificationMsg="Page now points somewhere new!" # String will be followed by redirect URL and location noscript is run from.
subredditsInput="${workingDir}/subreddits" # If present, is a sourced bash noscript that should define a ${subreddits[@]} array.
### Outputs: ##################################################################################################
logFile="${workingDir}/${noscriptBasename}.log"
lastRedirectFile="${workingDir}/lastRedirect"
subredditList="${workingDir}/subreddits.list"
website="${workingDir}/${noscriptBasename}.html"
sharedMemory="/dev/shm/${noscriptBasename}.shm"
namedPipe="/dev/shm/${noscriptBasename}.pipe"
###############################################################################################################
################## No need to modify anything below this line unless changing functionality ###################
###############################################################################################################
version="4" #Version 4 outputs to subreddits.list instead of subreddits.
version="5" #Version 5 reads subreddit array from subreddits file.
# Defines checkError(), which simply converts an exit code to a string denoscription.
# https://old.reddit.com/r/linuxquestions/comments/6nuoaq/how_can_i_look_up_exit_status_codes_reliably/
if [ -f "/home/${user}/.adms/ADMS-OS/noscripts/CommonScripts/error" ]; then
source "/home/${user}/.adms/ADMS-OS/noscripts/CommonScripts/error"
fi
###############################################################################################################
################################# Ideas for extending functionality: ##########################################
###############################################################################################################
# TODO: Should I install required packages if missing ???
###############################################################################################################
# Do I really want to make a distro indepandent check here?
# A lot is already done in "/home/${user}/noscripts/CommonScripts/packages"
# But no, I really don't....
# for package in
I've been hesitant to submit this in fear that I have re-invented the wheel here, but please tell me if I have.
#!/usr/bin/env bash
# Script to be placed in /etc/cron.d/cron.hourly
###############################################################################################################
# Ignore below comment, it's just for shellcheck. (Must appear before any instructions.) #
# shellcheck disable=SC1090 # Can't follow non-constant source #
# shellcheck disable=SC2034 # Yea, I have some unused variables #
###############################################################################################################
requiredPackages=(
alsa-utils
coreutils
curl
wc
wget
zenity
)
noscriptBasename=$(basename "${0}") # Could also user ${BASH_SOURCE[0]} here.
kibibyte="1024"
mebibyte="$(( kibibyte * kibibyte ))"
###############################################################################################################
########################################### Configuration Variables: ##########################################
###############################################################################################################
### Inputs: Wikipedia example ######################################################################################
user="user"
workingDir="/home/${user}/${noscriptBasename}"
audioOutputDevice="plughw:CARD=NVidia,DEV=3" # Get list of available devices with: aplay -L | grep "CARD"
maxLogSize="$((1 * mebibyte))" #bytes
notificationSound="${workingDir}/notify.wav"
urlToWatch="https://en.wikipedia.org/wiki/Redirect_page" # Will redirect to https://en.wikipedia.org/wiki/URL_redirection
notificatonTitle="Redirect change"
notificationMsg="Page now points somewhere new!" # String will be followed by redirect URL and location noscript is run from.
subredditsInput="${workingDir}/subreddits" # If present, is a sourced bash noscript that should define a ${subreddits[@]} array.
### Outputs: ##################################################################################################
logFile="${workingDir}/${noscriptBasename}.log"
lastRedirectFile="${workingDir}/lastRedirect"
subredditList="${workingDir}/subreddits.list"
website="${workingDir}/${noscriptBasename}.html"
sharedMemory="/dev/shm/${noscriptBasename}.shm"
namedPipe="/dev/shm/${noscriptBasename}.pipe"
###############################################################################################################
################## No need to modify anything below this line unless changing functionality ###################
###############################################################################################################
version="4" #Version 4 outputs to subreddits.list instead of subreddits.
version="5" #Version 5 reads subreddit array from subreddits file.
# Defines checkError(), which simply converts an exit code to a string denoscription.
# https://old.reddit.com/r/linuxquestions/comments/6nuoaq/how_can_i_look_up_exit_status_codes_reliably/
if [ -f "/home/${user}/.adms/ADMS-OS/noscripts/CommonScripts/error" ]; then
source "/home/${user}/.adms/ADMS-OS/noscripts/CommonScripts/error"
fi
###############################################################################################################
################################# Ideas for extending functionality: ##########################################
###############################################################################################################
# TODO: Should I install required packages if missing ???
###############################################################################################################
# Do I really want to make a distro indepandent check here?
# A lot is already done in "/home/${user}/noscripts/CommonScripts/packages"
# But no, I really don't....
# for package in
Wikipedia
URL redirection
technique for making a Web page available under more than one URL address
"${requiredPackages[@]}"; do
# :
# done
###############################################################################################################
# TODO: Should we use a named pipe for communication with subprocess instead ???
###############################################################################################################
# Would have to re-do a lot of logic for this route.
# if [ ! -p "${namedPipe}" ]; then
# mkfifo -m "a=rw" "${namedPipe}" #Man page literally says "not a=rw", but what does that mean?
# fi
###############################################################################################################
# TODO: Use array of URL's for tracking multiple websites.
###############################################################################################################
# Don't actually need this at all right now, but maybe one day...
###############################################################################################################
#Does not try to handle race-conditions, but I don't think it should not be a problem.
declare -A globalState;
function setGlobalState()
{
local -r varName="${1}"
local -r varValue="${2}"
if [ ${#} -eq 2 ]; then
globalState["${varName}"]="${varValue}"
fi
printf "# Using associative array for easy addition of new variables\n" | sudo tee "${sharedMemory}" > /dev/null
declare -p globalState | sudo tee -a "${sharedMemory}" > /dev/null
}
function getGlobalState()
{
local -r varName="${1}"
local -r varType="${2}"
local success=true
if [ -f "${sharedMemory}" ]; then
source "${sharedMemory}"
if [ ${#} -ge 1 ]; then
if [[ "${globalState[${varName}]}" != "" ]]; then
printf "%s" "${globalState[${varName}]}"
else
success=false
fi
fi
else
success=false
fi
if ! ${success}; then
if [[ ${varType} == "bool" ]]; then
printf "false";
elif [[ ${varType} == "int" ]]; then
printf "0";
elif [[ ${varType} == "string" ]]; then
printf "";
fi
return 1
fi
return 0
}
function cleanupSharedMemory()
{
if [ -f "${sharedMemory}" ]; then
sudo rm -vf "${sharedMemory}"
fi
}
setGlobalState "ring" "false"
dateFmt="+%Y.%m.%d_%I:%M%P"
#dateFmt="+%Y-%m-%d_%H:%M:%S.%3N"
function getDateTimeStamp()
{
date "${dateFmt}"
}
function getLogSize()
{
wc -c "${logFile}" | cut -f 1 -d ' '
}
function getLogLength()
{
wc -l "${logFile}" | cut -f 1 -d ' '
}
function log()
{
local -r extFmt="${1}"
printf "%s | ${extFmt}\n" "$(getDateTimeStamp)" "${@:2}" | tee -a "${logFile}"
}
function truncateLog()
{
local -r percentToKeep="${1}"
local -r logSize="$(getLogSize)"
local -r numLinesStart="$(getLogLength)"
# shellcheck disable=SC2155 # Masking return values by declaring and assigning together.
local numLines="$(echo "scale=0; ${numLinesStart} * ${percentToKeep}" | bc)"
numLines="${numLines%.*}" #Round down to nearest int.
# shellcheck disable=SC2005 # It's not a useless echo! It's not! I love echo...
echo "$(tail "-${numLines}" "${logFile}" 2> /dev/null)" > "${logFile}"
log "Trimmed output size: %b -> %b" "${logSize}" "$(getLogSize)"
log "Trimmed output size: %b -> %b" "${numLinesStart}" "$(getLogLength)"
}
printf -v dividerVar "<%.0s>%.0s" {1..80}
function divider()
{
printf "%b\n" "${dividerVar}">> "${logFile}"
}
function ringer()
{
local -r startVolume=$(amixer get Master | grep -o "[0-9]*%" | head -1) #Record current volume level
# shellcheck disable=SC2034 # The variable ${uid} is used when testing as cron job.
local -r uid=$(id -u "${user}")
local ring=true #Should always be true fist call.
if [[ "$(getGlobalState "ring")" != "${ring}" ]]; then
printf "Ringer was called with incorrect ring state! Check logical flow!\n"
fi
while ${ring}; do
amixer set Master 20% > /dev/null #I use headphones, and I don't want to blast out my eardrums
# Ok, weird one. Audio will not play over
# :
# done
###############################################################################################################
# TODO: Should we use a named pipe for communication with subprocess instead ???
###############################################################################################################
# Would have to re-do a lot of logic for this route.
# if [ ! -p "${namedPipe}" ]; then
# mkfifo -m "a=rw" "${namedPipe}" #Man page literally says "not a=rw", but what does that mean?
# fi
###############################################################################################################
# TODO: Use array of URL's for tracking multiple websites.
###############################################################################################################
# Don't actually need this at all right now, but maybe one day...
###############################################################################################################
#Does not try to handle race-conditions, but I don't think it should not be a problem.
declare -A globalState;
function setGlobalState()
{
local -r varName="${1}"
local -r varValue="${2}"
if [ ${#} -eq 2 ]; then
globalState["${varName}"]="${varValue}"
fi
printf "# Using associative array for easy addition of new variables\n" | sudo tee "${sharedMemory}" > /dev/null
declare -p globalState | sudo tee -a "${sharedMemory}" > /dev/null
}
function getGlobalState()
{
local -r varName="${1}"
local -r varType="${2}"
local success=true
if [ -f "${sharedMemory}" ]; then
source "${sharedMemory}"
if [ ${#} -ge 1 ]; then
if [[ "${globalState[${varName}]}" != "" ]]; then
printf "%s" "${globalState[${varName}]}"
else
success=false
fi
fi
else
success=false
fi
if ! ${success}; then
if [[ ${varType} == "bool" ]]; then
printf "false";
elif [[ ${varType} == "int" ]]; then
printf "0";
elif [[ ${varType} == "string" ]]; then
printf "";
fi
return 1
fi
return 0
}
function cleanupSharedMemory()
{
if [ -f "${sharedMemory}" ]; then
sudo rm -vf "${sharedMemory}"
fi
}
setGlobalState "ring" "false"
dateFmt="+%Y.%m.%d_%I:%M%P"
#dateFmt="+%Y-%m-%d_%H:%M:%S.%3N"
function getDateTimeStamp()
{
date "${dateFmt}"
}
function getLogSize()
{
wc -c "${logFile}" | cut -f 1 -d ' '
}
function getLogLength()
{
wc -l "${logFile}" | cut -f 1 -d ' '
}
function log()
{
local -r extFmt="${1}"
printf "%s | ${extFmt}\n" "$(getDateTimeStamp)" "${@:2}" | tee -a "${logFile}"
}
function truncateLog()
{
local -r percentToKeep="${1}"
local -r logSize="$(getLogSize)"
local -r numLinesStart="$(getLogLength)"
# shellcheck disable=SC2155 # Masking return values by declaring and assigning together.
local numLines="$(echo "scale=0; ${numLinesStart} * ${percentToKeep}" | bc)"
numLines="${numLines%.*}" #Round down to nearest int.
# shellcheck disable=SC2005 # It's not a useless echo! It's not! I love echo...
echo "$(tail "-${numLines}" "${logFile}" 2> /dev/null)" > "${logFile}"
log "Trimmed output size: %b -> %b" "${logSize}" "$(getLogSize)"
log "Trimmed output size: %b -> %b" "${numLinesStart}" "$(getLogLength)"
}
printf -v dividerVar "<%.0s>%.0s" {1..80}
function divider()
{
printf "%b\n" "${dividerVar}">> "${logFile}"
}
function ringer()
{
local -r startVolume=$(amixer get Master | grep -o "[0-9]*%" | head -1) #Record current volume level
# shellcheck disable=SC2034 # The variable ${uid} is used when testing as cron job.
local -r uid=$(id -u "${user}")
local ring=true #Should always be true fist call.
if [[ "$(getGlobalState "ring")" != "${ring}" ]]; then
printf "Ringer was called with incorrect ring state! Check logical flow!\n"
fi
while ${ring}; do
amixer set Master 20% > /dev/null #I use headphones, and I don't want to blast out my eardrums
# Ok, weird one. Audio will not play over
same device user is using, so we need to specify a different one.
# So, if user is using laptop speakers, we can play though properly equipped external HDMI montior.
# Also, the audio is muted for the first second of play, so we will play the sound twice, but hear it once.
sudo -H -i -u "${user}" "aplay" -D "${audioOutputDevice}" "${notificationSound}" "${notificationSound}"
# This version works if run by user directly (i.e. Not as cron job)
# aplay -D "${audioOutputDevice}" "${notificationSound}" "${notificationSound}" > /dev/null
amixer set Master "${startVolume}" > /dev/null #Reset volume to what it was before
sleep 1
ring=$(getGlobalState "ring" "bool")
done
setGlobalState "ring" "false"
}
function popup()
{
local -r website="${1}"
local -r width=400
local -r height=200
local -r noscript="${notificatonTitle}"
local -r message="${notificatonMsg}\n${1}\nThis dialoge was created by: $(realpath "${BASH_SOURCE[0]}")"
zenity \
--warning \
--text="${message}" \
--noscript="${noscript}" \
--width="${width}" \
--height="${height}"
}
function checkReDirect()
{
local -r lastRedirect="$( < "${lastRedirectFile}" )"
local currentRedirect=""
currentRedirect="$(curl -ILs -o /dev/null -w "%{url_effective}" "${urlToWatch}")"
curlCode="${?}"
if [ "${curlCode}" -ne 0 ]; then
if [[ "${ERROR_SOURCED}" == "true" ]]; then
log "$(checkError "curl" "${curlCode}")"
else
log "Error! curl failed with ${curlCode}"
fi
return
elif [[ "${currentRedirect}" == "${lastRedirect}" ]]; then
log "Executing: %b ( No news... )" "$(realpath "${BASH_SOURCE[0]}")"
return
else # This isn't needed since other cases do early return ...
log "Executing: %b ( NEWS!! )" "$(realpath "${BASH_SOURCE[0]}")"
listSubreddits
wget "${currentRedirect}" -O "${website}" # Grab page for analysis
redirectEnding=${lastRedirect%/} # Remove trailing slash if present
redirectEnding=${redirectEnding##*/} # Remove everything up to last slash (Shoud be left with last section of URL)
noscriptSuggestion="$(grep -o "<noscript>.*</noscript>" "${website}")" #TODO: Find better way to parse html
noscriptSuggestion="${noscriptSuggestion#*>}" # Strip off <noscript>
noscriptSuggestion="${noscriptSuggestion%<*}" # Strip off </noscript>
log "Title Suggestion: ${redirectEnding} - ${noscriptSuggestion}"
log "Opening %s\n" "${currentRedirect}"
printf "%s" "${currentRedirect}" > "${lastRedirectFile}"
setGlobalState "ring" "true"
ringer & # Non-blocking so it will keep ringing until killed.
ringerPID=${!} # Keep this as global variable.
#Attempt to open URL in default web-broswer
if command -v gnome-open > /dev/null; then
gnome-open "${currentRedirect}" &
[ -f "${subredditList}" ] && [ -s "${subredditList}" ] && gnome-open "${subredditList}" &
elif command -v xdg-open > /dev/null; then
xdg-open "${currentRedirect}" &
[ -f "${subredditList}" ] && [ -s "${subredditList}" ] && xdg-open "${subredditList}" &
elif command -v gio > /dev/null; then
gio open "${currentRedirect}" &
[ -f "${subredditList}" ] && [ -s "${subredditList}" ] && gio open "${subredditList}" &
fi
popup "${currentRedirect}" # Blocking command. Once popup is closed, we will kill the ringer.
setGlobalState "ring" "false" # Seems /dev/shm is the way to communicate with background processes.
printf "Popup closed. Waiting for ringer to end. [pid=%s]\n" "${ringerPID}"
wait "${ringerPID}"
printf "Ringer ended.\n"
fi
}
function listSubreddits()
{
# Maybe one of these subreddit will care about the URL change
if [ -f "${subredditsInput}" ]; then
# Expected format is simply to define an array named ${subreddits[@]}
# You can form that array however you want. Keep it simple, or go nuts.
source "${subredditsInput}"
fi
for subreddit in "${subreddits[@]%\/}"; do # Normalize sub names
# So, if user is using laptop speakers, we can play though properly equipped external HDMI montior.
# Also, the audio is muted for the first second of play, so we will play the sound twice, but hear it once.
sudo -H -i -u "${user}" "aplay" -D "${audioOutputDevice}" "${notificationSound}" "${notificationSound}"
# This version works if run by user directly (i.e. Not as cron job)
# aplay -D "${audioOutputDevice}" "${notificationSound}" "${notificationSound}" > /dev/null
amixer set Master "${startVolume}" > /dev/null #Reset volume to what it was before
sleep 1
ring=$(getGlobalState "ring" "bool")
done
setGlobalState "ring" "false"
}
function popup()
{
local -r website="${1}"
local -r width=400
local -r height=200
local -r noscript="${notificatonTitle}"
local -r message="${notificatonMsg}\n${1}\nThis dialoge was created by: $(realpath "${BASH_SOURCE[0]}")"
zenity \
--warning \
--text="${message}" \
--noscript="${noscript}" \
--width="${width}" \
--height="${height}"
}
function checkReDirect()
{
local -r lastRedirect="$( < "${lastRedirectFile}" )"
local currentRedirect=""
currentRedirect="$(curl -ILs -o /dev/null -w "%{url_effective}" "${urlToWatch}")"
curlCode="${?}"
if [ "${curlCode}" -ne 0 ]; then
if [[ "${ERROR_SOURCED}" == "true" ]]; then
log "$(checkError "curl" "${curlCode}")"
else
log "Error! curl failed with ${curlCode}"
fi
return
elif [[ "${currentRedirect}" == "${lastRedirect}" ]]; then
log "Executing: %b ( No news... )" "$(realpath "${BASH_SOURCE[0]}")"
return
else # This isn't needed since other cases do early return ...
log "Executing: %b ( NEWS!! )" "$(realpath "${BASH_SOURCE[0]}")"
listSubreddits
wget "${currentRedirect}" -O "${website}" # Grab page for analysis
redirectEnding=${lastRedirect%/} # Remove trailing slash if present
redirectEnding=${redirectEnding##*/} # Remove everything up to last slash (Shoud be left with last section of URL)
noscriptSuggestion="$(grep -o "<noscript>.*</noscript>" "${website}")" #TODO: Find better way to parse html
noscriptSuggestion="${noscriptSuggestion#*>}" # Strip off <noscript>
noscriptSuggestion="${noscriptSuggestion%<*}" # Strip off </noscript>
log "Title Suggestion: ${redirectEnding} - ${noscriptSuggestion}"
log "Opening %s\n" "${currentRedirect}"
printf "%s" "${currentRedirect}" > "${lastRedirectFile}"
setGlobalState "ring" "true"
ringer & # Non-blocking so it will keep ringing until killed.
ringerPID=${!} # Keep this as global variable.
#Attempt to open URL in default web-broswer
if command -v gnome-open > /dev/null; then
gnome-open "${currentRedirect}" &
[ -f "${subredditList}" ] && [ -s "${subredditList}" ] && gnome-open "${subredditList}" &
elif command -v xdg-open > /dev/null; then
xdg-open "${currentRedirect}" &
[ -f "${subredditList}" ] && [ -s "${subredditList}" ] && xdg-open "${subredditList}" &
elif command -v gio > /dev/null; then
gio open "${currentRedirect}" &
[ -f "${subredditList}" ] && [ -s "${subredditList}" ] && gio open "${subredditList}" &
fi
popup "${currentRedirect}" # Blocking command. Once popup is closed, we will kill the ringer.
setGlobalState "ring" "false" # Seems /dev/shm is the way to communicate with background processes.
printf "Popup closed. Waiting for ringer to end. [pid=%s]\n" "${ringerPID}"
wait "${ringerPID}"
printf "Ringer ended.\n"
fi
}
function listSubreddits()
{
# Maybe one of these subreddit will care about the URL change
if [ -f "${subredditsInput}" ]; then
# Expected format is simply to define an array named ${subreddits[@]}
# You can form that array however you want. Keep it simple, or go nuts.
source "${subredditsInput}"
fi
for subreddit in "${subreddits[@]%\/}"; do # Normalize sub names