---------------------------------------------------------------------- Prompt
# starship.toml#custom.input_color sets input style, PS0 resets it
# PS0='\[\e[0m\]'
if [[ $TERM_PROGRAM != @(vscode|zed) ]]; then
export STARSHIP_CONFIG=~/.config/starship/circles.toml
# export STARSHIP_CONFIG=~/.config/starship/dividers.toml
else
export STARSHIP_CONFIG=~/.config/starship/vscode-zed.toml
fi
# eval "$(starship init bash)"
# ---------------------------------------------------------------------- zoxide
# fucks up starship's status.pipestatus module
# eval "$(zoxide init bash)"
# ------------------------------------------------------------------------ tmux
if [[ $TERM_PROGRAM != @(tmux|vscode|zed) && "$DISPLAY" && -x "$(command -v tmux)" ]]; then
if [[ "$(tmux list-sessions -F '69' -f '#{==:#{session_attached},0}' 2> /dev/null)" ]]; then
tmux attach-session
else
tmux new-session
fi
fi
```
AS you may notice, all `eval`'s are commented out, so there's no shell integrations and stuff. I was initislly thinking its happening cause of `starship.rs` (prompt) but now it does not seem like so. Although `starship.rs` does show the different exit codes in the prompt. I'm not using `ble.sh` or https://github.com/rcaloras/bash-preexec
https://redd.it/1ostpgh
@r_bash
# starship.toml#custom.input_color sets input style, PS0 resets it
# PS0='\[\e[0m\]'
if [[ $TERM_PROGRAM != @(vscode|zed) ]]; then
export STARSHIP_CONFIG=~/.config/starship/circles.toml
# export STARSHIP_CONFIG=~/.config/starship/dividers.toml
else
export STARSHIP_CONFIG=~/.config/starship/vscode-zed.toml
fi
# eval "$(starship init bash)"
# ---------------------------------------------------------------------- zoxide
# fucks up starship's status.pipestatus module
# eval "$(zoxide init bash)"
# ------------------------------------------------------------------------ tmux
if [[ $TERM_PROGRAM != @(tmux|vscode|zed) && "$DISPLAY" && -x "$(command -v tmux)" ]]; then
if [[ "$(tmux list-sessions -F '69' -f '#{==:#{session_attached},0}' 2> /dev/null)" ]]; then
tmux attach-session
else
tmux new-session
fi
fi
```
AS you may notice, all `eval`'s are commented out, so there's no shell integrations and stuff. I was initislly thinking its happening cause of `starship.rs` (prompt) but now it does not seem like so. Although `starship.rs` does show the different exit codes in the prompt. I'm not using `ble.sh` or https://github.com/rcaloras/bash-preexec
https://redd.it/1ostpgh
@r_bash
GitHub
GitHub - rcaloras/bash-preexec: ⚡ preexec and precmd functions for Bash just like Zsh.
⚡ preexec and precmd functions for Bash just like Zsh. - GitHub - rcaloras/bash-preexec: ⚡ preexec and precmd functions for Bash just like Zsh.
Automating Mint Updates?
Context: I'm trying to write a hardening bash/shell noscript for Mint 21. In it, I'd like to automate these tasks:
* Set the “Refresh the list of updates automatically:” value to “Daily”
* Enable the "Apply updates automatically" option
* Enable the "Remove obsolete kernels and dependencies" option
I know all this could be done pretty quickly in Update Manager, but it's just one of many things I'm trying automate.
I thought it would be simple, since I believe Linux Mint stores these update settings in dconf(?)
This is what I tried:
`#!/bin/bash`
`# Linux Mint Update Manager Settings Script`
`# Set the refresh interval to daily (1 day = 1440 minutes)`
`dconf write /com/linuxmint/updates/refresh-minutes 1440`
`# Enable automatic updates`
`dconf write /com/linuxmint/updates/auto-update true`
`# Enable automatic removal of obsolete kernels`
`dconf write /com/linuxmint/updates/remove-obsolete-kernels true`
Using `dconf read` does verify the changes were applied, but I'd have thought that the changes would've reflected in the Update Manager GUI (like other changes I've made via the noscript have) but everything looks the same. Can anyone tell me if I'm doing something wrong?
https://redd.it/1ot57dw
@r_bash
Context: I'm trying to write a hardening bash/shell noscript for Mint 21. In it, I'd like to automate these tasks:
* Set the “Refresh the list of updates automatically:” value to “Daily”
* Enable the "Apply updates automatically" option
* Enable the "Remove obsolete kernels and dependencies" option
I know all this could be done pretty quickly in Update Manager, but it's just one of many things I'm trying automate.
I thought it would be simple, since I believe Linux Mint stores these update settings in dconf(?)
This is what I tried:
`#!/bin/bash`
`# Linux Mint Update Manager Settings Script`
`# Set the refresh interval to daily (1 day = 1440 minutes)`
`dconf write /com/linuxmint/updates/refresh-minutes 1440`
`# Enable automatic updates`
`dconf write /com/linuxmint/updates/auto-update true`
`# Enable automatic removal of obsolete kernels`
`dconf write /com/linuxmint/updates/remove-obsolete-kernels true`
Using `dconf read` does verify the changes were applied, but I'd have thought that the changes would've reflected in the Update Manager GUI (like other changes I've made via the noscript have) but everything looks the same. Can anyone tell me if I'm doing something wrong?
https://redd.it/1ot57dw
@r_bash
Reddit
From the bash community on Reddit
Explore this post and more from the bash community
busymd - A minimalist Markdown viewer for busy terminals in 300 lines of pure Bash.
https://redd.it/1otffwr
@r_bash
https://redd.it/1otffwr
@r_bash
Reddit
From the bash community on Reddit: busymd - A minimalist Markdown viewer for busy terminals in 300 lines of pure Bash.
Explore this post and more from the bash community
How do you centrally manage your Bash noscripts especially repeatable noscripts used in multiple server
So, I'm curious about how my fellow engineers handle multiple useful Bash noscripts. Especially when you have flints of servers.
Do you keep them in Git and pull from each host?
Or do you store them somewhere and just copy and paste whenever you want to use the noscript?
I'm exploring better ways to centrally organize, version, and run my repetitive Bash noscripts. Mostly when I have to run the same noscripts on multiple servers. Ideally something that does not need configuration management like Ansible.
Any suggestions? Advice? or better approach or tool used?
https://redd.it/1oslt0p
@r_bash
So, I'm curious about how my fellow engineers handle multiple useful Bash noscripts. Especially when you have flints of servers.
Do you keep them in Git and pull from each host?
Or do you store them somewhere and just copy and paste whenever you want to use the noscript?
I'm exploring better ways to centrally organize, version, and run my repetitive Bash noscripts. Mostly when I have to run the same noscripts on multiple servers. Ideally something that does not need configuration management like Ansible.
Any suggestions? Advice? or better approach or tool used?
https://redd.it/1oslt0p
@r_bash
Reddit
From the bash community on Reddit
Explore this post and more from the bash community
a tool for comparing present noscripts execution with past ouput
https://gist.github.com/jul/ef4cbc4f506caace73c3c38b91cb1ea2
https://redd.it/1ou4oj6
@r_bash
https://gist.github.com/jul/ef4cbc4f506caace73c3c38b91cb1ea2
https://redd.it/1ou4oj6
@r_bash
Gist
a framework for comparing present noscripts execution with past ouput
a framework for comparing present noscripts execution with past ouput - mr_freeze.sh
Template to Markdown File
Not sure if this already exists, but I wrote a small Bash tool that creates Markdown files from templates. It basically just copies a
I know this could just be done with a simple
workflow.github.com/AtonPomans/md\_template
https://redd.it/1oujchv
@r_bash
Not sure if this already exists, but I wrote a small Bash tool that creates Markdown files from templates. It basically just copies a
.md file from your templates directory to wherever you're working -- but with some added niceties like custom output names and persistent template directories. I know this could just be done with a simple
cp, but I like the simplicity this adds to my workflow. workflow.github.com/AtonPomans/md\_template
https://redd.it/1oujchv
@r_bash
GitHub
GitHub - AtonPomans/md_template: A simple shell CLI tool to create Markdown files from reusable templates.
A simple shell CLI tool to create Markdown files from reusable templates. - AtonPomans/md_template
I have made a very useful python3 noscript to pause the current process. Switches include: -p,--prompt "message"; -r, --response "message; -t, --timer <seconds>; -q,--quiet; -e,--echo; -h, --help; --version
Below is the link to a python3 noscript that allows for customization, including replacing the prompt, a response option, quiet mode, timer, and echoing to variable the key pressed. The program will echo "Press any key to continue..." indefinitely until either the user presses any key (but [Shift\] [CTRL\], [ALT\]), or the optional timer [--t | --timer\] reaches zero. Timer is shown in [00:00:00\] format where hours and minutes hide as it reaches zero until the final count is [00\]. The program allows for quiet running with no prompt, just a pause with cursor blink [-q | --quiet\] that must have a timer set as well in order to run. There is an option to place an alternative prompt which replaces the default with your own [-p | --prompt\] (Must be within double quotes) and the ability to also add response text to the output [-r | --response\] (Must be within double quotes). I have added the option to send the key press to stdout using [-e | --echo\] in order to be used with command substitution to populate variables and work with case statements, etc.
When I migrated to Linux from Windows/DOS, I was rather surprised that there wasn't some type of "pause" function of any sort within the basic functioning of Linux. I have played around with the noscript for a while and have tried to make this as close to pure bash as possible in every directive I used keeping commands to those built-in. I have also spent many hours trying very hard to get the time function o the countdown to be as accurate as possible using different sources but unfortunately there is no way to get the precision I was hoping for through simple bash. As it is now there is a loss of about a second during the course of an hour.
I wanted a function in bash where I could just give the command "pause" and it would pause and I have done that with a little extra.
The default prompt is "Press any key to continue..."
Usage: $ pause [-p|--prompt\] [-t|--timer\] [-r|--response\] [-h|--help\] [-q|--quiet \] [-e, --echo\]
https://github.com/Grawmpy/pause.py
#!/usr/bin/python3
# Denoscription: This noscript allows for the interruption of the current process until either
# the timer reaches 00, or the user presses any key. If no timer is used, the process
# will be stopped indefinitely until the press of any key except CTRL, ALT, Shift. Using
# the timer (in seconds only) continues the current process without user interaction. The order of the
# variables can be passed to the noscript in any order, doesn't matter, they are processed as they
# are read and the result is stored until applied to the final output.
#
# Example of code:
# $ pause
# $ Press any key to continue...
#
# $ pause -t 10 -p "Hello World" -r "Thank you, come again".
# $ 10 Hello World
# $ Thank you, come again.
#
# $ keypress=$(pause -e -p "Enter your selection: ")
# $ Enter your selection: f (key not echoed to monitor)
# $ echo $keypress
# $ f
#
# Options include: -t, --timer -p, --prompt -r, --response -e, --echo
# -t, --timer: pause -t 10 (Will display as 00h:00m:00s before the prompt)
# -p, --prompt: pause -p "Hello World"
# -r, --response: pause -r "Thank you, come again."
# -e, --echo: pause -e (Can be used in conjunction with command substitution keypress=$(pause -e) )
# -q, --quiet: pause -q -t10 Must be used wit timer
#
# The -e option will echo the single key press to the std out for populating variables to be used in
# case statements, etc.
#
# GPL3 License: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE
Below is the link to a python3 noscript that allows for customization, including replacing the prompt, a response option, quiet mode, timer, and echoing to variable the key pressed. The program will echo "Press any key to continue..." indefinitely until either the user presses any key (but [Shift\] [CTRL\], [ALT\]), or the optional timer [--t | --timer\] reaches zero. Timer is shown in [00:00:00\] format where hours and minutes hide as it reaches zero until the final count is [00\]. The program allows for quiet running with no prompt, just a pause with cursor blink [-q | --quiet\] that must have a timer set as well in order to run. There is an option to place an alternative prompt which replaces the default with your own [-p | --prompt\] (Must be within double quotes) and the ability to also add response text to the output [-r | --response\] (Must be within double quotes). I have added the option to send the key press to stdout using [-e | --echo\] in order to be used with command substitution to populate variables and work with case statements, etc.
When I migrated to Linux from Windows/DOS, I was rather surprised that there wasn't some type of "pause" function of any sort within the basic functioning of Linux. I have played around with the noscript for a while and have tried to make this as close to pure bash as possible in every directive I used keeping commands to those built-in. I have also spent many hours trying very hard to get the time function o the countdown to be as accurate as possible using different sources but unfortunately there is no way to get the precision I was hoping for through simple bash. As it is now there is a loss of about a second during the course of an hour.
I wanted a function in bash where I could just give the command "pause" and it would pause and I have done that with a little extra.
The default prompt is "Press any key to continue..."
Usage: $ pause [-p|--prompt\] [-t|--timer\] [-r|--response\] [-h|--help\] [-q|--quiet \] [-e, --echo\]
https://github.com/Grawmpy/pause.py
#!/usr/bin/python3
# Denoscription: This noscript allows for the interruption of the current process until either
# the timer reaches 00, or the user presses any key. If no timer is used, the process
# will be stopped indefinitely until the press of any key except CTRL, ALT, Shift. Using
# the timer (in seconds only) continues the current process without user interaction. The order of the
# variables can be passed to the noscript in any order, doesn't matter, they are processed as they
# are read and the result is stored until applied to the final output.
#
# Example of code:
# $ pause
# $ Press any key to continue...
#
# $ pause -t 10 -p "Hello World" -r "Thank you, come again".
# $ 10 Hello World
# $ Thank you, come again.
#
# $ keypress=$(pause -e -p "Enter your selection: ")
# $ Enter your selection: f (key not echoed to monitor)
# $ echo $keypress
# $ f
#
# Options include: -t, --timer -p, --prompt -r, --response -e, --echo
# -t, --timer: pause -t 10 (Will display as 00h:00m:00s before the prompt)
# -p, --prompt: pause -p "Hello World"
# -r, --response: pause -r "Thank you, come again."
# -e, --echo: pause -e (Can be used in conjunction with command substitution keypress=$(pause -e) )
# -q, --quiet: pause -q -t10 Must be used wit timer
#
# The -e option will echo the single key press to the std out for populating variables to be used in
# case statements, etc.
#
# GPL3 License: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE
GitHub
GitHub - Grawmpy/pause.py: Python3 noscript that allows for customization, including replacing the prompt, a response option, quiet…
Python3 noscript that allows for customization, including replacing the prompt, a response option, quiet mode, timer, and echoing to variable. - Grawmpy/pause.py
I have made a very useful python3 noscript to pause the current process. Switches include: -p,--prompt "message"; -r, --response "message; -t, --timer <seconds>; -q,--quiet; -e,--echo; -h, --help; --version
Below is the link to a python3 noscript that allows for customization, including replacing the prompt, a response option, quiet mode, timer, and echoing to variable the key pressed. The program will echo "Press any key to continue..." indefinitely until either the user presses any key (but \[Shift\] \[CTRL\], \[ALT\]), or the optional timer \[--t | --timer\] reaches zero. Timer is shown in \[00:00:00\] format where hours and minutes hide as it reaches zero until the final count is \[00\]. The program allows for quiet running with no prompt, just a pause with cursor blink \[-q | --quiet\] that must have a timer set as well in order to run. There is an option to place an alternative prompt which replaces the default with your own \[-p | --prompt\] (Must be within double quotes) and the ability to also add response text to the output \[-r | --response\] (Must be within double quotes). I have added the option to send the key press to stdout using \[-e | --echo\] in order to be used with command substitution to populate variables and work with case statements, etc.
When I migrated to Linux from Windows/DOS, I was rather surprised that there wasn't some type of "pause" function of any sort within the basic functioning of Linux. I have played around with the noscript for a while and have tried to make this as close to pure bash as possible in every directive I used keeping commands to those built-in. I have also spent many hours trying very hard to get the time function o the countdown to be as accurate as possible using different sources but unfortunately there is no way to get the precision I was hoping for through simple bash. As it is now there is a loss of about a second during the course of an hour.
I wanted a function in bash where I could just give the command "pause" and it would pause and I have done that with a little extra.
The default prompt is "Press any key to continue..."
Usage: $ pause \[-p|--prompt\] \[-t|--timer\] \[-r|--response\] \[-h|--help\] \[-q|--quiet \] \[-e, --echo\]
[https://github.com/Grawmpy/pause.py](https://github.com/Grawmpy/pause.py)
#!/usr/bin/python3
# Denoscription: This noscript allows for the interruption of the current process until either
# the timer reaches [00], or the user presses any key. If no timer is used, the process
# will be stopped indefinitely until the press of any key except [CTRL], [ALT], [Shift]. Using
# the timer (in seconds only) continues the current process without user interaction. The order of the
# variables can be passed to the noscript in any order, doesn't matter, they are processed as they
# are read and the result is stored until applied to the final output.
#
# Example of code:
# $ pause
# $ Press any key to continue...
#
# $ pause -t 10 -p "Hello World" -r "Thank you, come again".
# $ [10] Hello World
# $ Thank you, come again.
#
# $ keypress=$(pause -e -p "Enter your selection: ")
# $ Enter your selection: f (key not echoed to monitor)
# $ echo $keypress
# $ f
#
# Options include: [-t, --timer] [-p, --prompt] [-r, --response] [-e, --echo]
# -t, --timer: pause -t 10 (Will display as [00h:00m:00s] before the prompt)
# -p, --prompt: pause -p "Hello World"
# -r, --response: pause -r "Thank you, come again."
# -e, --echo: pause -e (Can be used in conjunction with command substitution keypress=$(pause -e) )
# -q, --quiet: pause -q -t10 [Must be used wit timer]
#
# The -e option will echo the single key press to the std out for populating variables to be used in
# case statements, etc.
#
# GPL3 License: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE
Below is the link to a python3 noscript that allows for customization, including replacing the prompt, a response option, quiet mode, timer, and echoing to variable the key pressed. The program will echo "Press any key to continue..." indefinitely until either the user presses any key (but \[Shift\] \[CTRL\], \[ALT\]), or the optional timer \[--t | --timer\] reaches zero. Timer is shown in \[00:00:00\] format where hours and minutes hide as it reaches zero until the final count is \[00\]. The program allows for quiet running with no prompt, just a pause with cursor blink \[-q | --quiet\] that must have a timer set as well in order to run. There is an option to place an alternative prompt which replaces the default with your own \[-p | --prompt\] (Must be within double quotes) and the ability to also add response text to the output \[-r | --response\] (Must be within double quotes). I have added the option to send the key press to stdout using \[-e | --echo\] in order to be used with command substitution to populate variables and work with case statements, etc.
When I migrated to Linux from Windows/DOS, I was rather surprised that there wasn't some type of "pause" function of any sort within the basic functioning of Linux. I have played around with the noscript for a while and have tried to make this as close to pure bash as possible in every directive I used keeping commands to those built-in. I have also spent many hours trying very hard to get the time function o the countdown to be as accurate as possible using different sources but unfortunately there is no way to get the precision I was hoping for through simple bash. As it is now there is a loss of about a second during the course of an hour.
I wanted a function in bash where I could just give the command "pause" and it would pause and I have done that with a little extra.
The default prompt is "Press any key to continue..."
Usage: $ pause \[-p|--prompt\] \[-t|--timer\] \[-r|--response\] \[-h|--help\] \[-q|--quiet \] \[-e, --echo\]
[https://github.com/Grawmpy/pause.py](https://github.com/Grawmpy/pause.py)
#!/usr/bin/python3
# Denoscription: This noscript allows for the interruption of the current process until either
# the timer reaches [00], or the user presses any key. If no timer is used, the process
# will be stopped indefinitely until the press of any key except [CTRL], [ALT], [Shift]. Using
# the timer (in seconds only) continues the current process without user interaction. The order of the
# variables can be passed to the noscript in any order, doesn't matter, they are processed as they
# are read and the result is stored until applied to the final output.
#
# Example of code:
# $ pause
# $ Press any key to continue...
#
# $ pause -t 10 -p "Hello World" -r "Thank you, come again".
# $ [10] Hello World
# $ Thank you, come again.
#
# $ keypress=$(pause -e -p "Enter your selection: ")
# $ Enter your selection: f (key not echoed to monitor)
# $ echo $keypress
# $ f
#
# Options include: [-t, --timer] [-p, --prompt] [-r, --response] [-e, --echo]
# -t, --timer: pause -t 10 (Will display as [00h:00m:00s] before the prompt)
# -p, --prompt: pause -p "Hello World"
# -r, --response: pause -r "Thank you, come again."
# -e, --echo: pause -e (Can be used in conjunction with command substitution keypress=$(pause -e) )
# -q, --quiet: pause -q -t10 [Must be used wit timer]
#
# The -e option will echo the single key press to the std out for populating variables to be used in
# case statements, etc.
#
# GPL3 License: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE
GitHub
GitHub - Grawmpy/pause.py: Python3 noscript that allows for customization, including replacing the prompt, a response option, quiet…
Python3 noscript that allows for customization, including replacing the prompt, a response option, quiet mode, timer, and echoing to variable. - Grawmpy/pause.py
AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import time
import sys
import argparse
import select
import tty
import termios
import os
SCRIPT = os.path.basename(sys.argv[0])
VERSION = '5.0.3' # Updated version number
AUTHOR = 'Grawmpy <Grawmpy@gmail.com> (CSPhelps)'
COPYRIGHT = """
GPL3.0 License. Software is intended as free use and is offered 'is is'
with no implied guarantees or copyrights."""
DESCRIPTION = """
A simple noscript that interrupts the current process until optional
timer reaches zero or the user presses any alphanumeric or [Enter]
key.
Optional custom prompt message and response text.
Allows for quiet mode with -q, --quiet [must be used in conjunction with -t, --timer <seconds>]
Command will interrupt process indefinitely until user presses any
alphanumeric key or optional timer reaches [00].
[ seconds are converted to [00h:00m:00s] style format ]
"""
DEFAULT_PROMPT = "Press any key to continue..."
def format_seconds(seconds):
"""Converts seconds into a [DD:HH:MM:SS] style format string."""
if seconds is None:
return ""
parts = []
days, seconds = divmod(seconds, 86400)
hours, seconds = divmod(seconds, 3600)
minutes, seconds = divmod(seconds, 60)
if days > 0:
parts.append(f"{days:02d}")
if hours > 0 or days > 0:
parts.append(f"{hours:02d}")
if minutes > 0 or hours > 0 or days > 0:
parts.append(f"{minutes:02d}")
# Seconds are always present
parts.append(f"{seconds:02d}")
return ":".join(parts)
def wait_for_key_or_timer(timeout=None, prompt=DEFAULT_PROMPT, response_text=None, quiet=False, echo_key=False):
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
HIDE_CURSOR = '\033[?25l'
SHOW_CURSOR = '\033[?25h'
ERASE_LINE = '\r\033[K'
pressed_key = None
try:
tty.setcbreak(fd)
start_time = time.time()
sys.stderr.write(HIDE_CURSOR)
sys.stderr.flush()
while True:
# Check for input immediately using select with a small timeout
# A 0.1 second timeout ensures we check for keys very frequently
if select.select([sys.stdin], [], [], 0.1)[0]:
pressed_key = sys.stdin.read(1)
break # Exit loop immediately on keypress
# Check time conditions
if timeout is not None:
elapsed_time = time.time() - start_time
remaining = int(timeout - elapsed_time)
if remaining <= 0:
break # Timer ran out
timer_display = format_seconds(remaining)
output = f"{ERASE_LINE}[{timer_display}] {prompt}\r"
else:
# If no timeout, show prompt only
output = f"{ERASE_LINE}{prompt}\r"
# Display output if not quiet
if not quiet:
sys.stderr.write(output)
sys.stderr.flush()
# Continue looping. The select.select(..., 0.1) handles the sleep/waiting.
# Clear final prompt line
sys.stderr.write(ERASE_LINE)
sys.stderr.flush()
finally:
# Restore original terminal settings
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
# Show the cursor again
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import time
import sys
import argparse
import select
import tty
import termios
import os
SCRIPT = os.path.basename(sys.argv[0])
VERSION = '5.0.3' # Updated version number
AUTHOR = 'Grawmpy <Grawmpy@gmail.com> (CSPhelps)'
COPYRIGHT = """
GPL3.0 License. Software is intended as free use and is offered 'is is'
with no implied guarantees or copyrights."""
DESCRIPTION = """
A simple noscript that interrupts the current process until optional
timer reaches zero or the user presses any alphanumeric or [Enter]
key.
Optional custom prompt message and response text.
Allows for quiet mode with -q, --quiet [must be used in conjunction with -t, --timer <seconds>]
Command will interrupt process indefinitely until user presses any
alphanumeric key or optional timer reaches [00].
[ seconds are converted to [00h:00m:00s] style format ]
"""
DEFAULT_PROMPT = "Press any key to continue..."
def format_seconds(seconds):
"""Converts seconds into a [DD:HH:MM:SS] style format string."""
if seconds is None:
return ""
parts = []
days, seconds = divmod(seconds, 86400)
hours, seconds = divmod(seconds, 3600)
minutes, seconds = divmod(seconds, 60)
if days > 0:
parts.append(f"{days:02d}")
if hours > 0 or days > 0:
parts.append(f"{hours:02d}")
if minutes > 0 or hours > 0 or days > 0:
parts.append(f"{minutes:02d}")
# Seconds are always present
parts.append(f"{seconds:02d}")
return ":".join(parts)
def wait_for_key_or_timer(timeout=None, prompt=DEFAULT_PROMPT, response_text=None, quiet=False, echo_key=False):
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
HIDE_CURSOR = '\033[?25l'
SHOW_CURSOR = '\033[?25h'
ERASE_LINE = '\r\033[K'
pressed_key = None
try:
tty.setcbreak(fd)
start_time = time.time()
sys.stderr.write(HIDE_CURSOR)
sys.stderr.flush()
while True:
# Check for input immediately using select with a small timeout
# A 0.1 second timeout ensures we check for keys very frequently
if select.select([sys.stdin], [], [], 0.1)[0]:
pressed_key = sys.stdin.read(1)
break # Exit loop immediately on keypress
# Check time conditions
if timeout is not None:
elapsed_time = time.time() - start_time
remaining = int(timeout - elapsed_time)
if remaining <= 0:
break # Timer ran out
timer_display = format_seconds(remaining)
output = f"{ERASE_LINE}[{timer_display}] {prompt}\r"
else:
# If no timeout, show prompt only
output = f"{ERASE_LINE}{prompt}\r"
# Display output if not quiet
if not quiet:
sys.stderr.write(output)
sys.stderr.flush()
# Continue looping. The select.select(..., 0.1) handles the sleep/waiting.
# Clear final prompt line
sys.stderr.write(ERASE_LINE)
sys.stderr.flush()
finally:
# Restore original terminal settings
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
# Show the cursor again
sys.stderr.write(SHOW_CURSOR)
sys.stderr.flush()
# --- Handle Post-Exit Logic (Outside the try...finally block) ---
if response_text:
sys.stderr.write(f"{response_text}\n")
sys.stderr.flush()
if echo_key and pressed_key:
sys.stdout.write(pressed_key)
sys.stdout.flush()
def main():
full_epilog = f"""
Default prompt: {DEFAULT_PROMPT}
Usage:
{SCRIPT} [-p|--prompt ] [-t|--timer ] [-r|--response ] [-h|--help] [-q|--quiet] [-e|--echo]
-p, --prompt [ input required (string must be in quotes) ]
-t, --timer [ number of seconds ]
-r, --response [ requires text (string must be in quotes) ]
-e, --echo [ echoes the key pressed to stdout if present. ]
-h, --help [ this information ]
-q, --quiet [ quiets text, requires timer be set. ]
Examples:
Input: $ {SCRIPT}
Output: $ {DEFAULT_PROMPT}
Input: $ {SCRIPT} -t <seconds>
Output: $ [timer] {DEFAULT_PROMPT}
Input: $ {SCRIPT} --prompt "Optional Prompt" --response "Your response"
Output: $ Optional Prompt
$ Your Response
Input: $ {SCRIPT} -p "Optional Prompt" -r "Your response"
Author: {AUTHOR}
{COPYRIGHT}
"""
parser = argparse.ArgumentParser(
denoscription=DESCRIPTION,
formatter_class=argparse.RawDenoscriptionHelpFormatter,
epilog=full_epilog # <-- Insert the detailed help message here
)
parser.add_argument('-t', '--timer', type=int, help='Number of seconds to wait.')
parser.add_argument('-p', '--prompt', type=str, default=DEFAULT_PROMPT, help='Custom prompt message.')
parser.add_argument('-r', '--response', type=str, help='Requires text to be displayed after interruption.')
parser.add_argument('-q', '--quiet', action='store_true', help='Quiets text, implicitly requires timer be set.')
parser.add_argument('-e', '--echo', action='store_true', help='Echoes the key pressed to stdout if present.')
parser.add_argument('--version', action='version', version=f'%(prog)s v{VERSION}')
args = parser.parse_args()
# Logic checks as per original bash noscript
if args.quiet and not args.timer:
print("Error: Timer must be set when using --quiet mode.")
sys.exit(1)
wait_for_key_or_timer(
timeout=args.timer,
prompt=args.prompt,
response_text=args.response,
quiet=args.quiet,
echo_key=args.echo # Pass the new argument
)
sys.exit(0)
if __name__ == "__main__":
# Check if we are running interactively, which is required for termios
if not sys.stdin.isatty():
print("This noscript requires an interactive terminal to function properly.")
sys.exit(1)
main()
https://redd.it/1ouqrrq
@r_bash
sys.stderr.flush()
# --- Handle Post-Exit Logic (Outside the try...finally block) ---
if response_text:
sys.stderr.write(f"{response_text}\n")
sys.stderr.flush()
if echo_key and pressed_key:
sys.stdout.write(pressed_key)
sys.stdout.flush()
def main():
full_epilog = f"""
Default prompt: {DEFAULT_PROMPT}
Usage:
{SCRIPT} [-p|--prompt ] [-t|--timer ] [-r|--response ] [-h|--help] [-q|--quiet] [-e|--echo]
-p, --prompt [ input required (string must be in quotes) ]
-t, --timer [ number of seconds ]
-r, --response [ requires text (string must be in quotes) ]
-e, --echo [ echoes the key pressed to stdout if present. ]
-h, --help [ this information ]
-q, --quiet [ quiets text, requires timer be set. ]
Examples:
Input: $ {SCRIPT}
Output: $ {DEFAULT_PROMPT}
Input: $ {SCRIPT} -t <seconds>
Output: $ [timer] {DEFAULT_PROMPT}
Input: $ {SCRIPT} --prompt "Optional Prompt" --response "Your response"
Output: $ Optional Prompt
$ Your Response
Input: $ {SCRIPT} -p "Optional Prompt" -r "Your response"
Author: {AUTHOR}
{COPYRIGHT}
"""
parser = argparse.ArgumentParser(
denoscription=DESCRIPTION,
formatter_class=argparse.RawDenoscriptionHelpFormatter,
epilog=full_epilog # <-- Insert the detailed help message here
)
parser.add_argument('-t', '--timer', type=int, help='Number of seconds to wait.')
parser.add_argument('-p', '--prompt', type=str, default=DEFAULT_PROMPT, help='Custom prompt message.')
parser.add_argument('-r', '--response', type=str, help='Requires text to be displayed after interruption.')
parser.add_argument('-q', '--quiet', action='store_true', help='Quiets text, implicitly requires timer be set.')
parser.add_argument('-e', '--echo', action='store_true', help='Echoes the key pressed to stdout if present.')
parser.add_argument('--version', action='version', version=f'%(prog)s v{VERSION}')
args = parser.parse_args()
# Logic checks as per original bash noscript
if args.quiet and not args.timer:
print("Error: Timer must be set when using --quiet mode.")
sys.exit(1)
wait_for_key_or_timer(
timeout=args.timer,
prompt=args.prompt,
response_text=args.response,
quiet=args.quiet,
echo_key=args.echo # Pass the new argument
)
sys.exit(0)
if __name__ == "__main__":
# Check if we are running interactively, which is required for termios
if not sys.stdin.isatty():
print("This noscript requires an interactive terminal to function properly.")
sys.exit(1)
main()
https://redd.it/1ouqrrq
@r_bash
Reddit
From the bash community on Reddit: I have made a very useful python3 noscript to pause the current process. Switches include: -p…
Explore this post and more from the bash community
This is my first bash noscript and I would love some feedback
I wanted to share my first bash noscript and get any feedback you may have. It is still a bit of a work in progress as I make little edits here and there. If possible I would like to add some kind of progress tracker for the MakeMKV part, maybe try to get the movie name from the disc drive instead of typing it, and maybe change it so I can rip from 2 different drives as I have over 1000 dvds to do. If you have any constructive advice on those or any other ideas to improve it that would be appreciated. I am intentionally storing the mkv file and mp4 file in different spots and intentionally burning the subnoscripts.
p.s. for getting the name from the disc, this is for jellyfin so the noscript format is Title (Year) [tmdbid-####\] so I'm not sure if there is a way to automate getting that.
#!/bin/bash
#This is to create an mkv in ~/Videos/movies using MakeMKV, then create an mp4 in external drive MoviesDrive using Handbrake.
echo "Enter movie noscript: "
read moviename
mkvdir="$HOME/Videos/movies/$moviename"
mkvfile="$mkvdir/$moviename.mkv"
mp4dir="/media/andrew/MoviesDrive/Movies/$moviename"
mp4file="$mp4dir/$moviename.mp4"
if [ -d "$mkvdir" ]; then
echo "$movie_name folder already exists on computer"
exit 1
else
mkdir -p "$mkvdir"
echo "*****$moviename folder created"
fi
if [ -d "$mp4_dir" ]; then
echo "$moviename folder already exists on drive*****"
exit 1
else
mkdir -p "$mp4dir"
echo "$mp4_dir folder created"
fi
makemkvcon mkv -r disc:0 all "$mkvdir" --minlength=4000 --robot
if [ $? -eq 0 ]; then
echo "*****Ripping completed for $moviename."
first_mkv_file="$(find "$mkv_dir" -name ".mkv" | head -n 1)"
if -f "$first_mkv_file" ; then
mv "$firstmkvfile" "$mkvfile"
echo "*****MKV renamed to $moviename.mkv"
else
echo "No MKV file found to rename"
exit 1
fi
else
echo "Ripping failed for $moviename.*****"
exit 1
fi
HandBrakeCLI -i "$mkvfile" -o "$mp4file" --subnoscript 1 -burned
if [ -f "$mp4file" ]; then
echo "Mp4 file created"
echo "$moviename" >> ~/Documents/rippedmovies.txt
if grep -qiF "$moviename" ~/Documents/rippedmovies.txt; then
echo "$movie_name added to ripped movies list"
else
echo "$movie_name not added to ripped movies list"
fi
printf "\a"; sleep 1; printf "\a"; sleep 1; printf "\a"
else
echo "Issue creating Mp4 file"
fi
https://redd.it/1ous37v
@r_bash
I wanted to share my first bash noscript and get any feedback you may have. It is still a bit of a work in progress as I make little edits here and there. If possible I would like to add some kind of progress tracker for the MakeMKV part, maybe try to get the movie name from the disc drive instead of typing it, and maybe change it so I can rip from 2 different drives as I have over 1000 dvds to do. If you have any constructive advice on those or any other ideas to improve it that would be appreciated. I am intentionally storing the mkv file and mp4 file in different spots and intentionally burning the subnoscripts.
p.s. for getting the name from the disc, this is for jellyfin so the noscript format is Title (Year) [tmdbid-####\] so I'm not sure if there is a way to automate getting that.
#!/bin/bash
#This is to create an mkv in ~/Videos/movies using MakeMKV, then create an mp4 in external drive MoviesDrive using Handbrake.
echo "Enter movie noscript: "
read moviename
mkvdir="$HOME/Videos/movies/$moviename"
mkvfile="$mkvdir/$moviename.mkv"
mp4dir="/media/andrew/MoviesDrive/Movies/$moviename"
mp4file="$mp4dir/$moviename.mp4"
if [ -d "$mkvdir" ]; then
echo "$movie_name folder already exists on computer"
exit 1
else
mkdir -p "$mkvdir"
echo "*****$moviename folder created"
fi
if [ -d "$mp4_dir" ]; then
echo "$moviename folder already exists on drive*****"
exit 1
else
mkdir -p "$mp4dir"
echo "$mp4_dir folder created"
fi
makemkvcon mkv -r disc:0 all "$mkvdir" --minlength=4000 --robot
if [ $? -eq 0 ]; then
echo "*****Ripping completed for $moviename."
first_mkv_file="$(find "$mkv_dir" -name ".mkv" | head -n 1)"
if -f "$first_mkv_file" ; then
mv "$firstmkvfile" "$mkvfile"
echo "*****MKV renamed to $moviename.mkv"
else
echo "No MKV file found to rename"
exit 1
fi
else
echo "Ripping failed for $moviename.*****"
exit 1
fi
HandBrakeCLI -i "$mkvfile" -o "$mp4file" --subnoscript 1 -burned
if [ -f "$mp4file" ]; then
echo "Mp4 file created"
echo "$moviename" >> ~/Documents/rippedmovies.txt
if grep -qiF "$moviename" ~/Documents/rippedmovies.txt; then
echo "$movie_name added to ripped movies list"
else
echo "$movie_name not added to ripped movies list"
fi
printf "\a"; sleep 1; printf "\a"; sleep 1; printf "\a"
else
echo "Issue creating Mp4 file"
fi
https://redd.it/1ous37v
@r_bash
Reddit
From the bash community on Reddit
Explore this post and more from the bash community
Is this a good image compression method
I want to create a noscript that performs image compression with the following rules and jpegoptim:
1. Limit the maximum height/width to 2560 pixels by proportional scaling.
2. Limit the file size to scaled (height width 0.15) bytes.
Is this plausible?
https://redd.it/1ovaze0
@r_bash
I want to create a noscript that performs image compression with the following rules and jpegoptim:
1. Limit the maximum height/width to 2560 pixels by proportional scaling.
2. Limit the file size to scaled (height width 0.15) bytes.
Is this plausible?
https://redd.it/1ovaze0
@r_bash
Reddit
From the bash community on Reddit
Explore this post and more from the bash community
Wayland Backlight LED solution help
github with the noscripts: https://github.com/somniasum/wayland-backlight-led
Hey guys so after switching from Xorg to Wayland, like aeons ago, I noticed there isn't support for keyboard backlight LED on Wayland yet.
Unlike on Xorg you could use 'xset led' for all that but guess that doesn't work on Wayland cause of like permissions and stuff? IDK.
Anyway I made some sort of solution for the LED stuff and it works just barely.
Reason being when pressing CAPS LOCK the LED turns off and stuff and isn't really persistent and stuff. So hopefully you guys can help with finding a better solution that's more persistent with the LED state.
Thanks in advance.
https://redd.it/1ovc65y
@r_bash
github with the noscripts: https://github.com/somniasum/wayland-backlight-led
Hey guys so after switching from Xorg to Wayland, like aeons ago, I noticed there isn't support for keyboard backlight LED on Wayland yet.
Unlike on Xorg you could use 'xset led' for all that but guess that doesn't work on Wayland cause of like permissions and stuff? IDK.
Anyway I made some sort of solution for the LED stuff and it works just barely.
Reason being when pressing CAPS LOCK the LED turns off and stuff and isn't really persistent and stuff. So hopefully you guys can help with finding a better solution that's more persistent with the LED state.
Thanks in advance.
https://redd.it/1ovc65y
@r_bash
GitHub
GitHub - somniasum/wayland-backlight-led: An alternative to 'xset' in Wayland for keyboard backlight LED
An alternative to 'xset' in Wayland for keyboard backlight LED - somniasum/wayland-backlight-led
where to correctly set PATH
I ran into a problem where a GUI program can't run a command because it can't find it. I realized it's because I only modify PATH inside .bashrc, so of course a program not started by bash would only see the default PATH.
where should I update PATH?
P.S. the default .profile already sources .bashrc but is somehow not exporting the variables? (otherwise I wouldn't have this problem)
https://redd.it/1ovfib3
@r_bash
I ran into a problem where a GUI program can't run a command because it can't find it. I realized it's because I only modify PATH inside .bashrc, so of course a program not started by bash would only see the default PATH.
where should I update PATH?
P.S. the default .profile already sources .bashrc but is somehow not exporting the variables? (otherwise I wouldn't have this problem)
https://redd.it/1ovfib3
@r_bash
Reddit
From the bash community on Reddit
Explore this post and more from the bash community
i am working on a posix virtual machine with reader macros so i can rewrite the rules of the shell live while its running, to interpret or wite a compiler for any language. moving beyond the syntax of posix by force. i have been told to ask questions rather than assert. i decline.
awkmacrovm(){ awk 'BEGIN{r0=0;r1=1;rx=1;ic=1;while(rx){x=substr(ci,ic,1);y=substr(ci,ic+1,1);z=substr(ci,ic+2,1);if(z == "-"){rx-=ry}; else if(z == "<"){rx=rx<ry}; else if(z == "m"){ry=rx}; else if(z == "$"){rx=system(ry)}; else if(z == "r"){rx=rr[y]}; else if(z == "w"){rr[y] = rx}; else if(z == "i"){getline rx}; else if(z == "o"){printf "%s", rx}; else if(z == "+"){rx=rx ry}; else if(z == "c"){rx = sprintf("%c", ry)}; else if(z == "#"){rx = ord(ry)}; else if(z == "s"){rx=substr(rx,ry,1)};else if(z == "x"){ic=-2;ci=rx}; ic+=3};};' ci="$1";};
https://redd.it/1ovj54b
@r_bash
awkmacrovm(){ awk 'BEGIN{r0=0;r1=1;rx=1;ic=1;while(rx){x=substr(ci,ic,1);y=substr(ci,ic+1,1);z=substr(ci,ic+2,1);if(z == "-"){rx-=ry}; else if(z == "<"){rx=rx<ry}; else if(z == "m"){ry=rx}; else if(z == "$"){rx=system(ry)}; else if(z == "r"){rx=rr[y]}; else if(z == "w"){rr[y] = rx}; else if(z == "i"){getline rx}; else if(z == "o"){printf "%s", rx}; else if(z == "+"){rx=rx ry}; else if(z == "c"){rx = sprintf("%c", ry)}; else if(z == "#"){rx = ord(ry)}; else if(z == "s"){rx=substr(rx,ry,1)};else if(z == "x"){ic=-2;ci=rx}; ic+=3};};' ci="$1";};
https://redd.it/1ovj54b
@r_bash
Reddit
From the bash community on Reddit
Explore this post and more from the bash community
potd (Pokémon of the Day) - a new random Pokémon for your terminal every day!
[silly little pokemon in the silly little terminal being silly little guys](https://preview.redd.it/ni9gt36fow0g1.png?width=1081&format=png&auto=webp&s=3a4e400a75f29f178f260b58dcc510844e277e4e)
Hi all :)
Just something silly I've been working on since last night. I'm sure it's been done a million times in a million better ways, so if you are aware of any others I'd love to see them!
The noscript uses [pokeget-rs](https://github.com/talwat/pokeget-rs) to retrieve the sprites, so make sure it's available in your $PATH before running this.
Every time the noscript is launched it seeds the $RANDOM value in bash with the current date as a unix timestamp (snapped to 00:00). This value is used to generate the Pokédex ID, ensuring the same Pokémon appears consistently for the entire day.
After that, $RANDOM is seeded again using the current date as a unix timestamp (this time snapped to the last 5 minutes). This value is used to check if the Pokémon should be shiny (1/128 chance), meaning that a Pokémon can be shiny for 5 minutes before the next roll happens.
I also added `--fetch` as an argument which will display a few lines of info next to the sprite:
1. `kn` is the current kernel version
2. `sh` is the current shell
3. `up` is the current uptime
4. `potd` lists the Pokémon's name followed by it's Pokédex ID in parenthesis
5. `seen` shows when you first saw this Pokémon
6. `shny` shows when you first saw the shiny variant of this Pokémon
If you have any tips on how I could improve this, please let me know! It's just a fun little thing I'm working on but I'd love to make it more efficient.
Full noscript:
#!/usr/bin/env bash
for i in "$@"; do
case $i in
"-v" | "--verbose")
# output the pokemon info to stderr
OPT_VERBOSE=1
;;
"-f" | "--fetch")
# include system info alongside the sprite
OPT_FETCH=1
;;
esac
done
CONFIG_DIR=${XDG_CONFIG_HOME:-$HOME/.config} # should almost always return `$HOME/.config`
POTD_DIR="${CONFIG_DIR}/potd" # the config directory that this noscript will use to store everything
POTD_CACHE="${POTD_DIR}/cache" # used to record which sprites have appeared before
POKEGET_CMD='pokeget' # requires pokeget-rs for the pretty small sprites
POKEGET_ARGS=('') # add any extra args for pokeget-rs here
MAX_DEX_ID=905 # max pokedex id in pokeget-rs. decrease this number to limit to specific generations.
# ansi escape codes for colours + style
HEAD='\e[34m'
DATA='\033[38;2;200;166;247m'
DATA='\e[35m'
SHINY='\e[33m'
BOLD='\e[1m'
RESET='\e[0m'
# seed the bash random number with the current date, snapped to midnight, as a unix timestamp
pokemon_seed=$(date --date "00:00" +%s)
RANDOM=${pokemon_seed}
pokedex_id=$((RANDOM % MAX_DEX_ID))
POKEGET_ARGS=("$pokedex_id" "${POKEGET_ARGS[@]}")
sprite_path="${POTD_CACHE}/${pokedex_id}"
# roll for a shiny
shiny_seed=$(date +%s)
shiny_seed=$((shiny_seed - (shiny_seed % 300)))
RANDOM=${shiny_seed}
shiny_roll=$((RANDOM % 128))
if [ $shiny_roll -eq 0 ]; then
POKEGET_ARGS+=('--shiny')
sprite_path="${sprite_path}-shiny"
fi
# check if this sprite has been saved yet
[ -d ${POTD_DIR} ] || mkdir ${POTD_DIR}
[ -d ${POTD_CACHE} ] || mkdir ${POTD_CACHE}
if ! [ -f ${sprite_path} ]; then
echo "$pokemon_seed" >$sprite_path # first seen value
$POKEGET_CMD ${POKEGET_ARGS[@]} >>$sprite_path 2>&1
fi
pokemon_name="$(sed '2q;d' $sprite_path)"
first_seen="$(head -n 1 $sprite_path)"
# extract the shiny encounter date if available
if [ $shiny_roll -eq 0 ]; then
shiny_seen=$(head -n 1 "${sprite_path}")
else
[ -f "${sprite_path}-shiny" ] && shiny_seen=$(head -n 1 "${sprite_path}-shiny") || shiny_seen=0
fi
# get
[silly little pokemon in the silly little terminal being silly little guys](https://preview.redd.it/ni9gt36fow0g1.png?width=1081&format=png&auto=webp&s=3a4e400a75f29f178f260b58dcc510844e277e4e)
Hi all :)
Just something silly I've been working on since last night. I'm sure it's been done a million times in a million better ways, so if you are aware of any others I'd love to see them!
The noscript uses [pokeget-rs](https://github.com/talwat/pokeget-rs) to retrieve the sprites, so make sure it's available in your $PATH before running this.
Every time the noscript is launched it seeds the $RANDOM value in bash with the current date as a unix timestamp (snapped to 00:00). This value is used to generate the Pokédex ID, ensuring the same Pokémon appears consistently for the entire day.
After that, $RANDOM is seeded again using the current date as a unix timestamp (this time snapped to the last 5 minutes). This value is used to check if the Pokémon should be shiny (1/128 chance), meaning that a Pokémon can be shiny for 5 minutes before the next roll happens.
I also added `--fetch` as an argument which will display a few lines of info next to the sprite:
1. `kn` is the current kernel version
2. `sh` is the current shell
3. `up` is the current uptime
4. `potd` lists the Pokémon's name followed by it's Pokédex ID in parenthesis
5. `seen` shows when you first saw this Pokémon
6. `shny` shows when you first saw the shiny variant of this Pokémon
If you have any tips on how I could improve this, please let me know! It's just a fun little thing I'm working on but I'd love to make it more efficient.
Full noscript:
#!/usr/bin/env bash
for i in "$@"; do
case $i in
"-v" | "--verbose")
# output the pokemon info to stderr
OPT_VERBOSE=1
;;
"-f" | "--fetch")
# include system info alongside the sprite
OPT_FETCH=1
;;
esac
done
CONFIG_DIR=${XDG_CONFIG_HOME:-$HOME/.config} # should almost always return `$HOME/.config`
POTD_DIR="${CONFIG_DIR}/potd" # the config directory that this noscript will use to store everything
POTD_CACHE="${POTD_DIR}/cache" # used to record which sprites have appeared before
POKEGET_CMD='pokeget' # requires pokeget-rs for the pretty small sprites
POKEGET_ARGS=('') # add any extra args for pokeget-rs here
MAX_DEX_ID=905 # max pokedex id in pokeget-rs. decrease this number to limit to specific generations.
# ansi escape codes for colours + style
HEAD='\e[34m'
DATA='\033[38;2;200;166;247m'
DATA='\e[35m'
SHINY='\e[33m'
BOLD='\e[1m'
RESET='\e[0m'
# seed the bash random number with the current date, snapped to midnight, as a unix timestamp
pokemon_seed=$(date --date "00:00" +%s)
RANDOM=${pokemon_seed}
pokedex_id=$((RANDOM % MAX_DEX_ID))
POKEGET_ARGS=("$pokedex_id" "${POKEGET_ARGS[@]}")
sprite_path="${POTD_CACHE}/${pokedex_id}"
# roll for a shiny
shiny_seed=$(date +%s)
shiny_seed=$((shiny_seed - (shiny_seed % 300)))
RANDOM=${shiny_seed}
shiny_roll=$((RANDOM % 128))
if [ $shiny_roll -eq 0 ]; then
POKEGET_ARGS+=('--shiny')
sprite_path="${sprite_path}-shiny"
fi
# check if this sprite has been saved yet
[ -d ${POTD_DIR} ] || mkdir ${POTD_DIR}
[ -d ${POTD_CACHE} ] || mkdir ${POTD_CACHE}
if ! [ -f ${sprite_path} ]; then
echo "$pokemon_seed" >$sprite_path # first seen value
$POKEGET_CMD ${POKEGET_ARGS[@]} >>$sprite_path 2>&1
fi
pokemon_name="$(sed '2q;d' $sprite_path)"
first_seen="$(head -n 1 $sprite_path)"
# extract the shiny encounter date if available
if [ $shiny_roll -eq 0 ]; then
shiny_seen=$(head -n 1 "${sprite_path}")
else
[ -f "${sprite_path}-shiny" ] && shiny_seen=$(head -n 1 "${sprite_path}-shiny") || shiny_seen=0
fi
# get
system info (shamelessly lifted from cutefetch)
get_uptime() {
local up=$(uptime)
up=${up#*up } # remove everything before "up "
up=${up%%,*} # remove everything after first comma
echo $up | xargs # trim whitespace
}
systeminfo=()
if ! [ -z ${OPT_FETCH+x} ]; then
systeminfo[0]="${BOLD}${HEAD}kn${RESET} ${DATA}$(uname -r | cut -f1 -d '-')"
systeminfo[1]="${BOLD}${HEAD}sh${RESET} ${DATA}$(basename $SHELL)"
systeminfo[2]="${BOLD}${HEAD}up${RESET} ${DATA}$(get_uptime)"
# store the pokemon info along with the system info
[ $shiny_roll -eq 0 ] && systeminfo[4]="${BOLD}${HEAD}potd${RESET} ${BOLD}${SHINY}${pokemon_name,,} (${pokedex_id})" || systeminfo[4]="${BOLD}${HEAD}potd${RESET} ${DATA}${pokemon_name,,} (${pokedex_id})"
[ $first_seen -eq $pokemon_seed ] && systeminfo[5]="${BOLD}${HEAD}seen${RESET} ${DATA}today" || systeminfo[5]="${BOLD}${HEAD}seen${RESET} ${DATA}$((first_seen % 60 % 60 % 24)) days ago"
case $shiny_seen in
0)
systeminfo[6]="${BOLD}${HEAD}shny${RESET} ${DATA}never seen"
;;
$pokemon_seed)
systeminfo[6]="${BOLD}${HEAD}shny${RESET} ${DATA}today"
;;
*)
systeminfo[6]="${BOLD}${HEAD}shny${RESET} ${DATA}$((shiny_seen % 60 % 60 % 24)) days ago"
;;
esac
fi
# print the pokemon info to stderr if -v or --verbose was passed
[ -z ${OPT_VERBOSE+x} ] || >&2 echo -e "dex_id: ${pokedex_id}\npkmn_name: ${pokemon_name}\nshiny_roll: ${shiny_roll}\npkmn_seed: ${pokemon_seed}\nshiny_seed: ${shiny_seed}\nfirst_seen: ${first_seen}"
# iterate over every line in the sprite, appending system info when available
index=0
tail -n +3 ${sprite_path} | while IFS= read -r line; do
[ $index -le ${#systeminfo[@]} ] && echo -e "${line} ${systeminfo[$index]}" || echo "${line}"
index=$((index + 1))
done
https://redd.it/1ovk9rn
@r_bash
get_uptime() {
local up=$(uptime)
up=${up#*up } # remove everything before "up "
up=${up%%,*} # remove everything after first comma
echo $up | xargs # trim whitespace
}
systeminfo=()
if ! [ -z ${OPT_FETCH+x} ]; then
systeminfo[0]="${BOLD}${HEAD}kn${RESET} ${DATA}$(uname -r | cut -f1 -d '-')"
systeminfo[1]="${BOLD}${HEAD}sh${RESET} ${DATA}$(basename $SHELL)"
systeminfo[2]="${BOLD}${HEAD}up${RESET} ${DATA}$(get_uptime)"
# store the pokemon info along with the system info
[ $shiny_roll -eq 0 ] && systeminfo[4]="${BOLD}${HEAD}potd${RESET} ${BOLD}${SHINY}${pokemon_name,,} (${pokedex_id})" || systeminfo[4]="${BOLD}${HEAD}potd${RESET} ${DATA}${pokemon_name,,} (${pokedex_id})"
[ $first_seen -eq $pokemon_seed ] && systeminfo[5]="${BOLD}${HEAD}seen${RESET} ${DATA}today" || systeminfo[5]="${BOLD}${HEAD}seen${RESET} ${DATA}$((first_seen % 60 % 60 % 24)) days ago"
case $shiny_seen in
0)
systeminfo[6]="${BOLD}${HEAD}shny${RESET} ${DATA}never seen"
;;
$pokemon_seed)
systeminfo[6]="${BOLD}${HEAD}shny${RESET} ${DATA}today"
;;
*)
systeminfo[6]="${BOLD}${HEAD}shny${RESET} ${DATA}$((shiny_seen % 60 % 60 % 24)) days ago"
;;
esac
fi
# print the pokemon info to stderr if -v or --verbose was passed
[ -z ${OPT_VERBOSE+x} ] || >&2 echo -e "dex_id: ${pokedex_id}\npkmn_name: ${pokemon_name}\nshiny_roll: ${shiny_roll}\npkmn_seed: ${pokemon_seed}\nshiny_seed: ${shiny_seed}\nfirst_seen: ${first_seen}"
# iterate over every line in the sprite, appending system info when available
index=0
tail -n +3 ${sprite_path} | while IFS= read -r line; do
[ $index -le ${#systeminfo[@]} ] && echo -e "${line} ${systeminfo[$index]}" || echo "${line}"
index=$((index + 1))
done
https://redd.it/1ovk9rn
@r_bash
Reddit
From the bash community on Reddit
Explore this post and more from the bash community
OC An image compression bash
This is an image compression bash I made to do the following tasks (jpg, jpeg only):
1. Limit the maximum height/width to 2560 pixels by proportional scaling.
2. Limit the file size to scaled (height * width * 0.15) bytes.
\---
https://redd.it/1ow3302
@r_bash
This is an image compression bash I made to do the following tasks (jpg, jpeg only):
1. Limit the maximum height/width to 2560 pixels by proportional scaling.
2. Limit the file size to scaled (height * width * 0.15) bytes.
\---
#!/bin/bashmax_dim=2560for input in *.jpg; do# Skip if no jpg files found[ -e "$input" ] || continueoutput="${input%.*}_compressed.jpg"# Get original dimensionswidth=$(identify -format "%w" "$input")height=$(identify -format "%h" "$input")# Check if resizing is neededif [ $width -le $max_dim ] && [ $height -le $max_dim ]; then# No resize needed, just copy input to outputcp "$input" "$output"target_width=$widthtarget_height=$heightelse# Determine scale factor to limit max dimension to 2560 pixelsif [ $width -gt $height ]; thenscale=$(echo "scale=4; $max_dim / $width" | bc)elsescale=$(echo "scale=4; $max_dim / $height" | bc)fi# Calculate new dimensions after scalingtarget_width=$(printf "%.0f" $(echo "$width * $scale" | bc))target_height=$(printf "%.0f" $(echo "$height * $scale" | bc))# Resize image proportionally with ImageMagick convertconvert "$input" -resize "${target_width}x${target_height}" "$output"fi# Calculate target file size limit in bytes (width * height * 0.15)target_size=$(printf "%.0f" $(echo "$target_width * $target_height * 0.15" | bc))actual_size=$(stat -c%s "$output")# Run jpegoptim only if target_size is less than actual file sizeif [ $target_size -lt $actual_size ]; thenjpegoptim --size=${target_size} --strip-all "$output"actual_size=$(stat -c%s "$output")fiecho "Processed $input -> $output"echo "Final dimensions: ${target_width}x${target_height}"echo "Final file size: $actual_size bytes (target was $target_size bytes)"donehttps://redd.it/1ow3302
@r_bash
Reddit
From the bash community on Reddit
Explore this post and more from the bash community
Decompression & Interpretation Of JPEG
As the noscript suggests could you potentially do a decompression of advanced file systems such as JPEG or PNG, but the limitation of using bash builtins (Use ‘type -t {command}’ to check if a command is built in) only, & preferably running ok.
https://redd.it/1owxgcu
@r_bash
As the noscript suggests could you potentially do a decompression of advanced file systems such as JPEG or PNG, but the limitation of using bash builtins (Use ‘type -t {command}’ to check if a command is built in) only, & preferably running ok.
https://redd.it/1owxgcu
@r_bash
Reddit
From the bash community on Reddit
Explore this post and more from the bash community