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
by removing trailing slash if present.
subreddit="${subreddit##*\/}" # Normalize sub names by removing any subreddit prefix.
printf "https://old.reddit.com/r/%s\n" "${subreddit}"
done > "${subredditList}"
}
###############################################################################################################
############ Script Start #####################################################################################
###############################################################################################################
divider
# To list hourly noscripts that run.
# sudo run-parts --report --test /etc/cron.hourly
# If started as root, then re-start as "${user}": (https://askubuntu.com/a/1105580)
if [ "$(id -u)" -eq 0 ]; then
log "Refusing to run as root!"
#exit; #Don't run as root.
exec sudo -H -u "${user}" bash -c "${0}" "${@}" #Force run as user.
echo "This is never reached."
fi
# ${DISPLAY} is typically unset when root sudo's to user.
if [ -z "${DISPLAY+unset}" ]; then
export DISPLAY=":0.0"
fi
log "Running as \${USER}=${USER} id=$(id -u). Script version = ${version}"
function exitCron()
{
printf "Exiting due to interrupt\n" >> "${logFile}"
if [ -n "${ringerPID}" ] && ps -p "${ringerPID}" > /dev/null; then
kill -15 "${ringerPID}"
fi
# unset traps.
trap - SIGHUP
trap - SIGINT
trap - SIGQUIT
trap - SIGTERM
cleanupSharedMemory
exit 1
}
#Don't think this is nessesary, but just make sure we exit each process when told to.
trap exitCron SIGHUP SIGINT SIGQUIT SIGTERM
if [ ! -d "${workingDir}" ]; then
mkdir -p "${workingDir}"
fi
# For loop will excute once every 600 seconds (10 minutes) for an hour
# shellcheck disable=SC2034 # Not using variable ${i}
for i in {0..3599..600}; do
checkReDirect
#break; #Uncomment to run once for testing.
sleep 600;
done
logSize="$(getLogSize)"
#Trim log length by about 10% if we have gone over ${maxLogSize}.
if (( "${logSize}" > "${maxLogSize}" )); then
truncateLog "0.90"
fi
cleanupSharedMemory
###############################################################################################################
# References:
#
# Check if variable is empty or unset:
# https://stackoverflow.com/questions/3601515/how-to-check-if-a-variable-is-set-in-bash
# https://www.cyberciti.biz/faq/unix-linux-bash-noscript-check-if-variable-is-empty/
#
# Send variable to background process:
# https://stackoverflow.com/questions/13207292/bash-background-process-modify-global-variable
#
# Limit log size keeping last n lines:
# https://unix.stackexchange.com/questions/310860/how-do-you-keep-only-the-last-n-lines-of-a-log-file
#
###############################################################################################################
https://redd.it/z7endd
@r_bash
subreddit="${subreddit##*\/}" # Normalize sub names by removing any subreddit prefix.
printf "https://old.reddit.com/r/%s\n" "${subreddit}"
done > "${subredditList}"
}
###############################################################################################################
############ Script Start #####################################################################################
###############################################################################################################
divider
# To list hourly noscripts that run.
# sudo run-parts --report --test /etc/cron.hourly
# If started as root, then re-start as "${user}": (https://askubuntu.com/a/1105580)
if [ "$(id -u)" -eq 0 ]; then
log "Refusing to run as root!"
#exit; #Don't run as root.
exec sudo -H -u "${user}" bash -c "${0}" "${@}" #Force run as user.
echo "This is never reached."
fi
# ${DISPLAY} is typically unset when root sudo's to user.
if [ -z "${DISPLAY+unset}" ]; then
export DISPLAY=":0.0"
fi
log "Running as \${USER}=${USER} id=$(id -u). Script version = ${version}"
function exitCron()
{
printf "Exiting due to interrupt\n" >> "${logFile}"
if [ -n "${ringerPID}" ] && ps -p "${ringerPID}" > /dev/null; then
kill -15 "${ringerPID}"
fi
# unset traps.
trap - SIGHUP
trap - SIGINT
trap - SIGQUIT
trap - SIGTERM
cleanupSharedMemory
exit 1
}
#Don't think this is nessesary, but just make sure we exit each process when told to.
trap exitCron SIGHUP SIGINT SIGQUIT SIGTERM
if [ ! -d "${workingDir}" ]; then
mkdir -p "${workingDir}"
fi
# For loop will excute once every 600 seconds (10 minutes) for an hour
# shellcheck disable=SC2034 # Not using variable ${i}
for i in {0..3599..600}; do
checkReDirect
#break; #Uncomment to run once for testing.
sleep 600;
done
logSize="$(getLogSize)"
#Trim log length by about 10% if we have gone over ${maxLogSize}.
if (( "${logSize}" > "${maxLogSize}" )); then
truncateLog "0.90"
fi
cleanupSharedMemory
###############################################################################################################
# References:
#
# Check if variable is empty or unset:
# https://stackoverflow.com/questions/3601515/how-to-check-if-a-variable-is-set-in-bash
# https://www.cyberciti.biz/faq/unix-linux-bash-noscript-check-if-variable-is-empty/
#
# Send variable to background process:
# https://stackoverflow.com/questions/13207292/bash-background-process-modify-global-variable
#
# Limit log size keeping last n lines:
# https://unix.stackexchange.com/questions/310860/how-do-you-keep-only-the-last-n-lines-of-a-log-file
#
###############################################################################################################
https://redd.it/z7endd
@r_bash
Press ctrl z and type bg from a bash noscript automatically
So i have a timer i run from telegram connected to my pc. Do anyone know if there is a possibility to automatically stop the noscript and ”automatically” put it under ”jobs” without ”&” when started.
Currently i have to manually press ctrl z and then type bg
https://redd.it/z7avv4
@r_bash
So i have a timer i run from telegram connected to my pc. Do anyone know if there is a possibility to automatically stop the noscript and ”automatically” put it under ”jobs” without ”&” when started.
Currently i have to manually press ctrl z and then type bg
https://redd.it/z7avv4
@r_bash
reddit
Press ctrl z and type bg from a bash noscript automatically
So i have a timer i run from telegram connected to my pc. Do anyone know if there is a possibility to automatically stop the noscript and...
pass to xargs
Hello I'm trying to process the output of \.
I run:
The output should be the full path of *.
This is what I have (not working):
can someone help?
https://redd.it/z7r0aj
@r_bash
Hello I'm trying to process the output of \.
I run:
mynoscript * to process all files in the current directory.The output should be the full path of *.
This is what I have (not working):
echo ${@:1} | tr '\n' '\0' | xargs -0 -I "%" realpath "%" can someone help?
https://redd.it/z7r0aj
@r_bash
reddit
pass * to xargs
Hello I'm trying to process the output of \*. I run: `mynoscript *` to process all files in the current directory. The output should be the full...
How to make tests in
I am using this snippet from an AskUbuntu post in my own
if "$color_prompt" = yes ; then
# when system is accessed via SSH, hostname with light grey background
if [ $(pstree -s $$) = *sshd* ]; then sshbg="[\03348;5;7m\"; fi
# when used as root, change username to orange and '#' to red for prompt
if $(id -u) -eq 0 ; then usercol="[\03338;5;3m\"; hashcol="[\03338;5;1m\"; else usercol="[\03338;5;2m\"; fi
# bash PS1 prompt
PS1="${usercol}\u[$(tput sgr0)\]@[$(tput sgr0)\][\03338;5;4m\${sshbg}\h[$(tput sgr0)\]:[$(tput sgr0)\][\03338;5;6m\\w[$(tput sgr0)\]${hashcol}\\$ [$(tput sgr0)\]"
unset sshbg rootcol hashcol
fi
I can test similar to line 3 above if
So far, I have:
if "$color_prompt" = yes ; then
# when system is accessed via SSH, hostname with light grey background
if [ $(pstree -s $$) = *sshd* ]; then
sshbg="[\03348;5;7m\"
elif [ $(pstree -s $$) = *"tmux: server"* ]; then
if [ $(pstree -s $(pgrep "tmux: client")) = *sshd* ]; then
sshbg="[\03348;5;7m\"
fi
fi
# when used as root, change username to orange and '#' to red for prompt
...
Is there any better, especially faster way? Since it generates
https://redd.it/z8033h
@r_bash
.bashrc so they execute as fast as possible?I am using this snippet from an AskUbuntu post in my own
.bashrc, but would like to improve it so it works also in a tmux session:if "$color_prompt" = yes ; then
# when system is accessed via SSH, hostname with light grey background
if [ $(pstree -s $$) = *sshd* ]; then sshbg="[\03348;5;7m\"; fi
# when used as root, change username to orange and '#' to red for prompt
if $(id -u) -eq 0 ; then usercol="[\03338;5;3m\"; hashcol="[\03338;5;1m\"; else usercol="[\03338;5;2m\"; fi
# bash PS1 prompt
PS1="${usercol}\u[$(tput sgr0)\]@[$(tput sgr0)\][\03338;5;4m\${sshbg}\h[$(tput sgr0)\]:[$(tput sgr0)\][\03338;5;6m\\w[$(tput sgr0)\]${hashcol}\\$ [$(tput sgr0)\]"
unset sshbg rootcol hashcol
fi
I can test similar to line 3 above if
pstree -s $$ returns tmux: server, and if it does, I can test [[ $(pstree -s $(pgrep "tmux: client")) = *sshd* ]] to get the desired result.So far, I have:
if "$color_prompt" = yes ; then
# when system is accessed via SSH, hostname with light grey background
if [ $(pstree -s $$) = *sshd* ]; then
sshbg="[\03348;5;7m\"
elif [ $(pstree -s $$) = *"tmux: server"* ]; then
if [ $(pstree -s $(pgrep "tmux: client")) = *sshd* ]; then
sshbg="[\03348;5;7m\"
fi
fi
# when used as root, change username to orange and '#' to red for prompt
...
Is there any better, especially faster way? Since it generates
PS1, I would like it to be as fast as possible to not be annoying.https://redd.it/z8033h
@r_bash
Ask Ubuntu
Is it possible to check if a connection is local or via ssh *after* elevating to the root account with `sudo`?
I want to see if I'm connected via ssh or running a local terminal.
If I just ssh into a server without changing to root via sudo, it's easy. Any of the variables $SSH_CLIENT, $SSH_CONNECTION or $S...
If I just ssh into a server without changing to root via sudo, it's easy. Any of the variables $SSH_CLIENT, $SSH_CONNECTION or $S...
read command removes empty lines
#!/usr/bin/env bash
ls ??-??.json | while IFS= read -r line; do ./noscripts/add-missing-strings.js "$line"; done
What I have already tried:-played with ifs-read -r-started questioning if the problem is really here and not in the .js
All files - https://github.com/RDKRACZ/for-reddit/tree/main/noscripts
https://redd.it/z8955d
@r_bash
#!/usr/bin/env bash
ls ??-??.json | while IFS= read -r line; do ./noscripts/add-missing-strings.js "$line"; done
What I have already tried:-played with ifs-read -r-started questioning if the problem is really here and not in the .js
All files - https://github.com/RDKRACZ/for-reddit/tree/main/noscripts
https://redd.it/z8955d
@r_bash
GitHub
for-reddit/noscripts at main · RDKRACZ/for-reddit
Contribute to RDKRACZ/for-reddit development by creating an account on GitHub.
Is there any way to have a "longterm history" in addition to the normal history?
I like to keep a record of all the commands I have run on my VPS, because it's a good reference for how I installed or configured something many months ago. So I have my
HISTFILESIZE=10000, and HISTSIZE=10000
along with
export PROMPTCOMMAND="history -a; history -c; history -r;$PROMPTCOMMAND"
to keep the history file up to date after each command. But my command item numbers are in the 5000's now, so it's a little inconvenient to search through such a long history when I'm looking for something I just used a few days ago. Is there any way to to write to a file like .historylong in addition to my normal history? That way I could keep my normal history shorter and only reference the "indefinite history" when needed. And would there be any way to have .historylong displayed with a command line number that I could use in the infrequent times that I want to run something from long ago like:
!4573
https://redd.it/z8vubd
@r_bash
I like to keep a record of all the commands I have run on my VPS, because it's a good reference for how I installed or configured something many months ago. So I have my
HISTFILESIZE=10000, and HISTSIZE=10000
along with
export PROMPTCOMMAND="history -a; history -c; history -r;$PROMPTCOMMAND"
to keep the history file up to date after each command. But my command item numbers are in the 5000's now, so it's a little inconvenient to search through such a long history when I'm looking for something I just used a few days ago. Is there any way to to write to a file like .historylong in addition to my normal history? That way I could keep my normal history shorter and only reference the "indefinite history" when needed. And would there be any way to have .historylong displayed with a command line number that I could use in the infrequent times that I want to run something from long ago like:
!4573
https://redd.it/z8vubd
@r_bash
reddit
Is there any way to have a "longterm history" in addition to the...
I like to keep a record of all the commands I have run on my VPS, because it's a good reference for how I installed or configured something many...
Why does sed delete the file's content when an output redirection is performed on the file, and not when using the append >> redirection?
For example, assume file.txt has the following content:
This is an example.
When I invoked the following command
But invoking this command
This is an example.
This is an EXAMPLE.
Isn't the output of
https://redd.it/z8x9c8
@r_bash
For example, assume file.txt has the following content:
This is an example.
When I invoked the following command
sed '/s/example/EXAMPLE/' file.txt > file.txt, the file's content was deleted.But invoking this command
sed '/s/example/EXAMPLE/' file.txt >> file.txt, produces the following output:This is an example.
This is an EXAMPLE.
Isn't the output of
sed produced on the stdout, and then the redirection operator redirects that output and rewrites the file?https://redd.it/z8x9c8
@r_bash
reddit
Why does sed delete the file's content when an output redirection...
For example, assume file.txt has the following content: This is an example. When I invoked the following command `sed '/s/example/EXAMPLE/'...
Any way to keep the path context while running bash noscripts in other bash noscripts?
Im trying to make a noscript that will automate the process for running a server for a game "Unturned". My noscript only has this line of code:
su - steam -c "./Steam/steamapps/common/U3DS/ServerHelper.sh +LanServer/MyServer"
where it runs a file as the steam user in the steam user home directory, which inside that file, the last line runs:
./UnturnedHeadless.x8664 -batchmode -nographics "$@"
which SHOULD run the
./Steam/steamapps/common/U3DS/ServerHelper.sh: line 18: ./UnturnedHeadless.x8664: No such file or directory
that file that its looking for being in the same folder as
https://redd.it/z8wzei
@r_bash
Im trying to make a noscript that will automate the process for running a server for a game "Unturned". My noscript only has this line of code:
su - steam -c "./Steam/steamapps/common/U3DS/ServerHelper.sh +LanServer/MyServer"
where it runs a file as the steam user in the steam user home directory, which inside that file, the last line runs:
./UnturnedHeadless.x8664 -batchmode -nographics "$@"
which SHOULD run the
Unturned_Headless.x86_64 file, but doesnt, instead giving this error:./Steam/steamapps/common/U3DS/ServerHelper.sh: line 18: ./UnturnedHeadless.x8664: No such file or directory
that file that its looking for being in the same folder as
ServerHelper.sh . Im guessing that this is due it somehow not keeping the context of what dir its in while running the ServerHelper.sh file. Anyone know how i could fix it? (also, sorry if im making any dumb mistakes, ive never done any bash noscripting before)https://redd.it/z8wzei
@r_bash
reddit
Any way to keep the path context while running bash noscripts in...
Im trying to make a noscript that will automate the process for running a server for a game "Unturned". My noscript only has this line of code: ...
I'm trying to understand bash
How do i create magic file school.mgc that can be used with the command file to detect School
data files, and School data files always contain the string SCHOOL at offset 0
https://redd.it/z90nlo
@r_bash
How do i create magic file school.mgc that can be used with the command file to detect School
data files, and School data files always contain the string SCHOOL at offset 0
https://redd.it/z90nlo
@r_bash
reddit
I'm trying to understand bash
How do i create magic file school.mgc that can be used with the command file to detect School data files, and School data files always contain...
DRY for this noscript?
My noscript feels pretty hideous for a lot of reasons. It seems like I should be storing the slack requests as vars but my attempts to do that were not working so I ended up with this functional but truly ugly noscript.
If you have any suggestions can you explain the how and the why? Def trying to develop better intuition about these things
​
set -euo pipefail
if pgrep java; then
printf "App10 already running. Nothing more to do"
curl -X POST -H 'Content-type: application/json' --data '{
"attachments":
{
"text":"APP10 Java services already running. Nothing more to do",
"mrkdwn_in":["text",
"color":"#bfeff",
"noscript":"TeamCity App10 Action Report"
}
]}' https://hooks.slack.com/services/XXXX
else
sudo -i -u rlsmgr bash << EOF
echo "Starting APP10 Java Services"
echo "Verifying we are now rlsmgr"
whoami
source /home/rlsmgr/start-java.ksh
if pgrep java; then
printf "APP10 has been started and is now running."
curl -X POST -H 'Content-type: application/json' --data '{
"attachments":
{
"text":"APP10 has been started and is now running",
"mrkdwn_in":["text",
"color":"#bfeff",
"noscript":"TeamCity App10 Action Report"
}
]}' https://hooks.slack.com/services/XXX
else
printf "APP10 did not start."
curl -X POST -H 'Content-type: application/json' --data '{
"attachments":
{
"text":"APP10 did not start",
"mrkdwn_in":["text",
"color":"#bfeff",
"noscript":"TeamCity App10 Action Report"
}
]}' https://hooks.slack.com/services/XXXX
fi
EOF
fi
https://redd.it/z92cm4
@r_bash
My noscript feels pretty hideous for a lot of reasons. It seems like I should be storing the slack requests as vars but my attempts to do that were not working so I ended up with this functional but truly ugly noscript.
If you have any suggestions can you explain the how and the why? Def trying to develop better intuition about these things
​
set -euo pipefail
if pgrep java; then
printf "App10 already running. Nothing more to do"
curl -X POST -H 'Content-type: application/json' --data '{
"attachments":
{
"text":"APP10 Java services already running. Nothing more to do",
"mrkdwn_in":["text",
"color":"#bfeff",
"noscript":"TeamCity App10 Action Report"
}
]}' https://hooks.slack.com/services/XXXX
else
sudo -i -u rlsmgr bash << EOF
echo "Starting APP10 Java Services"
echo "Verifying we are now rlsmgr"
whoami
source /home/rlsmgr/start-java.ksh
if pgrep java; then
printf "APP10 has been started and is now running."
curl -X POST -H 'Content-type: application/json' --data '{
"attachments":
{
"text":"APP10 has been started and is now running",
"mrkdwn_in":["text",
"color":"#bfeff",
"noscript":"TeamCity App10 Action Report"
}
]}' https://hooks.slack.com/services/XXX
else
printf "APP10 did not start."
curl -X POST -H 'Content-type: application/json' --data '{
"attachments":
{
"text":"APP10 did not start",
"mrkdwn_in":["text",
"color":"#bfeff",
"noscript":"TeamCity App10 Action Report"
}
]}' https://hooks.slack.com/services/XXXX
fi
EOF
fi
https://redd.it/z92cm4
@r_bash
docs.slack.dev
Slack platform overview | Slack Developer Docs
To jump straight into developing your own Slack app, follow our Quickstart. You can get started right now.
output of arp -a to variable
Hi all!
I'm new to bash, am looking at tutorials but cant figure this specific one out.
What I am trying to do is write a noscript that can find my vacuum robots IP address. My plan is to use 'arp -a', look through the client names and then use the IP address of the client that matches the expected name. However, my first lines of code:
yield me
So, the output of arp is properly being passed on to client_list and the first line is displayed, but it is then interpreted as a command? What am I doing wrong and how should I iterate through this list if not like this?
Thanks!
https://redd.it/z8vohf
@r_bash
Hi all!
I'm new to bash, am looking at tutorials but cant figure this specific one out.
What I am trying to do is write a noscript that can find my vacuum robots IP address. My plan is to use 'arp -a', look through the client names and then use the IP address of the client that matches the expected name. However, my first lines of code:
#!/bin/bash client_list= $(arp -a) echo "$client_list" #trying to get the full output of arp -a for client in a do echo ">>> $client" # trying to get a single row from arp -ayield me
line 2: <VACUUM_ROBOT_NAME>: command not foundSo, the output of arp is properly being passed on to client_list and the first line is displayed, but it is then interpreted as a command? What am I doing wrong and how should I iterate through this list if not like this?
Thanks!
https://redd.it/z8vohf
@r_bash
reddit
output of arp -a to variable
Hi all! I'm new to bash, am looking at tutorials but cant figure this specific one out. What I am trying to do is write a noscript that can find...
best practises for organizing/refactoring noscript of thousand of lines
Hi everybody,
I question myself if there is a better way to organize my 3k lines noscript.
Actually it is organized as follow:
1. general constraints section
2. function section
3. main section
Main section itself contains a three sections menu for system config, docker containers config and experimental config (:D). The noscript it is used by me to easily reconfigure this or that on my debian based headless homeservers or vps.
Now, because of its length, it is going difficult to manage, if I need to add or modify a function I have to jump to the beginning and then return to the point where the add or the modify must be done.
An idea I have is to create different indipendent noscript for each function, but this have some side effects, the main is I have to jump from one file to another and this will happen very often because I include in the noscript all the bash codes I write for my lab (after some tests...) so I do not forget anything. Maybe this is a classic approach even if I have to rewrite the most of the noscript to replace functions with noscripts and related parameters; functions too should be redesigned a little bit, and I'll have to rethink a way of using global constraints
I also think I have to find a way to avoid that these noscripts may be directly executed, by mistake (by me, in the end :D), from the shell without be recalled from the "main", because otherwise I should rewrite them in a way they cannot damage files or folders etc.
I have other craxy ideas but before describing them and break my head on them I'm at a point where suggestions from experts are not only welcome but needed.
Hoping that I explain clearly, I look forward your messages!
https://redd.it/z95dch
@r_bash
Hi everybody,
I question myself if there is a better way to organize my 3k lines noscript.
Actually it is organized as follow:
1. general constraints section
2. function section
3. main section
Main section itself contains a three sections menu for system config, docker containers config and experimental config (:D). The noscript it is used by me to easily reconfigure this or that on my debian based headless homeservers or vps.
Now, because of its length, it is going difficult to manage, if I need to add or modify a function I have to jump to the beginning and then return to the point where the add or the modify must be done.
An idea I have is to create different indipendent noscript for each function, but this have some side effects, the main is I have to jump from one file to another and this will happen very often because I include in the noscript all the bash codes I write for my lab (after some tests...) so I do not forget anything. Maybe this is a classic approach even if I have to rewrite the most of the noscript to replace functions with noscripts and related parameters; functions too should be redesigned a little bit, and I'll have to rethink a way of using global constraints
I also think I have to find a way to avoid that these noscripts may be directly executed, by mistake (by me, in the end :D), from the shell without be recalled from the "main", because otherwise I should rewrite them in a way they cannot damage files or folders etc.
I have other craxy ideas but before describing them and break my head on them I'm at a point where suggestions from experts are not only welcome but needed.
Hoping that I explain clearly, I look forward your messages!
https://redd.it/z95dch
@r_bash
reddit
best practises for organizing/refactoring noscript of thousand of lines
Hi everybody, I question myself if there is a better way to organize my 3k lines noscript. Actually it is organized as follow: 1. general...
How to make this one line .bat file into .sh file?
Hi folks.
Can someone please help me with this? I need this very simple .bat noscript to convert into .sh:
How should this be written for .sh?
Thank you in advance!
https://redd.it/z9866r
@r_bash
Hi folks.
Can someone please help me with this? I need this very simple .bat noscript to convert into .sh:
REM batch_audiowaveform.bat for %%F in (*.flac) do audiowaveform -i "%%F" -o "%%~nF.json" -b 8 -z 128How should this be written for .sh?
Thank you in advance!
https://redd.it/z9866r
@r_bash
reddit
How to make this one line .bat file into .sh file?
Hi folks. Can someone please help me with this? I need this very simple .bat noscript to convert into .sh: `REM batch_audiowaveform.bat` `for...