./chat - A minimal curl-based chatbot with ability to noscript and run code (tutorial && code)
I've been thinking a lot about "Life Copilots" && automating automations and recently discovered Bash Scripting while looking for ways to run code on my devices without root
To my surprise, Bash has been around since the 80s and works on basically anything that can run or emulate a shell including Linux but also Windows, macOS, Android, iOS, robots, drones, smart devices, and everything else new and old!
Even now my hands shake with excitement at the thought of using just one noscript for literally everything...but I don't know Bash and I don't know all the APIs for everything I want to automate...
...so I've started working on `./chat`, a prototype chatbot client in Bash with no dependencies besides `curl` (and an AI model) in \~200 lines of code
**🚨 Please Note: **This is very experimental and extremely risky...use a sandbox, container, or virtual machine to experiment
# Features
* No dependencies except `curl` and an AI model
* Chat histories and logs
* Write and execute shell code
* Pipe and chain `./chat` with itself or any other command
# What can it do?
* Chat inside the terminal
* Create, run, and automate other Bash noscripts
* Install packages and automate your shell
* Autonomously write and execute Python, NodeJS, etc
* Make and compile files
* Improve it's own source code
* Technically you should be able to create agents that act on their own using a simple `plan -> execute -> review` agent loop
# Setup
1. Copy the noscript below into a file called chat: `touch chat`
2. Make it executable: `chmod +x` `chat`
3. Run `./chat` for first time to add your API and model
1. Get an API key from https://openrouter.ai/models
1. Want to run your own models instead? Start here and see below for connecting your own model:
2. Pick a model, see here for free ones: https://openrouter.ai/models?max\_price=0
1. Copy+paste company/model, eg: `google/gemini-pro-1.5-exp`
3. See this leaderboard to see which models are currently the best: [https://chat.lmsys.org/?leaderboard](https://chat.lmsys.org/?leaderboard)
4. Ask me for suggestions below with your use case
5. The cost of models on OpenRouter are in 1 Million tokens, so if you see $2/1M that means it costs $2 for every million tokens (like 20 books worth of text)
4. Chat: `./chat "Your prompt here"`
5. Clear history and logs: `./chat --clear`
6. Temporarily change model: `./chat "Your prompt" --model "org/model-name"`
**If #3 doesn't work, create a chat.config file that looks like this:**
`OPENROUTER_API_KEY='sk-or-v1-xxxxxxxxxxxxx'`
`OPENROUTER_MODEL='openai/gpt-4o-2024-08-06'`
# Basic Usage
# Simple chat
./chat "Hello! What can you do?"
# Create and run a noscript
./chat "Write a bash noscript that lists all .txt files in the current directory"
https://preview.redd.it/9tgj2pm2qvhd1.png?width=1442&format=png&auto=webp&s=b81548aabbb9e2553dc4f4ec60205365ca61af28
https://preview.redd.it/vgf9sc7cqvhd1.png?width=1413&format=png&auto=webp&s=0076ac187182653bdd1634aa3feb93706e9a8515
# Advanced Usage
🍒 C**herry-picked results:** The examples below were handpicked to demonstrate capabilities, it's not guaranteed to produce working code 100% yet
# Generate a Python noscript and then explain it
./chat "Write a Python noscript that calculates the Fibonacci sequence" | ./chat "Explain the Python code"
# Use different models in a pipeline
./chat "Write a short story about a robot" --model "anthropic/claude-3-opus-20240229" |
./chat "Summarize it in one sentence" --model "openai/gpt-3.5-turbo"
# Generate and analyze code
./chat "Write a simple Java class for a bank account" |
./chat "Analyze the Java code for potential improvements"
# Multi-step task: Generate, translate, and summarize
./chat "Write a short story about AI" |
./chat "Translate it to French" |
./chat "Summarize it in
I've been thinking a lot about "Life Copilots" && automating automations and recently discovered Bash Scripting while looking for ways to run code on my devices without root
To my surprise, Bash has been around since the 80s and works on basically anything that can run or emulate a shell including Linux but also Windows, macOS, Android, iOS, robots, drones, smart devices, and everything else new and old!
Even now my hands shake with excitement at the thought of using just one noscript for literally everything...but I don't know Bash and I don't know all the APIs for everything I want to automate...
...so I've started working on `./chat`, a prototype chatbot client in Bash with no dependencies besides `curl` (and an AI model) in \~200 lines of code
**🚨 Please Note: **This is very experimental and extremely risky...use a sandbox, container, or virtual machine to experiment
# Features
* No dependencies except `curl` and an AI model
* Chat histories and logs
* Write and execute shell code
* Pipe and chain `./chat` with itself or any other command
# What can it do?
* Chat inside the terminal
* Create, run, and automate other Bash noscripts
* Install packages and automate your shell
* Autonomously write and execute Python, NodeJS, etc
* Make and compile files
* Improve it's own source code
* Technically you should be able to create agents that act on their own using a simple `plan -> execute -> review` agent loop
# Setup
1. Copy the noscript below into a file called chat: `touch chat`
2. Make it executable: `chmod +x` `chat`
3. Run `./chat` for first time to add your API and model
1. Get an API key from https://openrouter.ai/models
1. Want to run your own models instead? Start here and see below for connecting your own model:
2. Pick a model, see here for free ones: https://openrouter.ai/models?max\_price=0
1. Copy+paste company/model, eg: `google/gemini-pro-1.5-exp`
3. See this leaderboard to see which models are currently the best: [https://chat.lmsys.org/?leaderboard](https://chat.lmsys.org/?leaderboard)
4. Ask me for suggestions below with your use case
5. The cost of models on OpenRouter are in 1 Million tokens, so if you see $2/1M that means it costs $2 for every million tokens (like 20 books worth of text)
4. Chat: `./chat "Your prompt here"`
5. Clear history and logs: `./chat --clear`
6. Temporarily change model: `./chat "Your prompt" --model "org/model-name"`
**If #3 doesn't work, create a chat.config file that looks like this:**
`OPENROUTER_API_KEY='sk-or-v1-xxxxxxxxxxxxx'`
`OPENROUTER_MODEL='openai/gpt-4o-2024-08-06'`
# Basic Usage
# Simple chat
./chat "Hello! What can you do?"
# Create and run a noscript
./chat "Write a bash noscript that lists all .txt files in the current directory"
https://preview.redd.it/9tgj2pm2qvhd1.png?width=1442&format=png&auto=webp&s=b81548aabbb9e2553dc4f4ec60205365ca61af28
https://preview.redd.it/vgf9sc7cqvhd1.png?width=1413&format=png&auto=webp&s=0076ac187182653bdd1634aa3feb93706e9a8515
# Advanced Usage
🍒 C**herry-picked results:** The examples below were handpicked to demonstrate capabilities, it's not guaranteed to produce working code 100% yet
# Generate a Python noscript and then explain it
./chat "Write a Python noscript that calculates the Fibonacci sequence" | ./chat "Explain the Python code"
# Use different models in a pipeline
./chat "Write a short story about a robot" --model "anthropic/claude-3-opus-20240229" |
./chat "Summarize it in one sentence" --model "openai/gpt-3.5-turbo"
# Generate and analyze code
./chat "Write a simple Java class for a bank account" |
./chat "Analyze the Java code for potential improvements"
# Multi-step task: Generate, translate, and summarize
./chat "Write a short story about AI" |
./chat "Translate it to French" |
./chat "Summarize it in
OpenRouter
Models | OpenRouter
Browse models on OpenRouter
English"
https://preview.redd.it/yftl7f2l2whd1.png?width=1883&format=png&auto=webp&s=ca5bb1424ed22760fc71a6e8abb532dce91e88b7
# Integration with Unix tools
# Save output to a file
./chat "Write a short report on climate change" > climate_report.txt
# Count words in generated content
./chat "Write a haiku about the singularity" | tee >(wc -w)
# Process file contents
cat complicated_code.py | ./chat "Explain this Python code and suggest optimizations"
# Data analysis
cat large_dataset.csv | ./chat "Analyze this CSV data and provide insights"
https://preview.redd.it/gehidtqn3whd1.png?width=1378&format=png&auto=webp&s=4f099a8be45cc847d380014ddfa84d74923dc1e5
# What about offline or custom models?
This noscript was intentionally kept simple so you can adapt it to work with any server and model, including offline and self hosted ones
Almost all the leading Large Langauge Models are compatible with the OpenAI API, which is what this noscript is built around. If you have a custom setup, simply copy+paste the noscript into your favorite chatbot like [claude.ai](http://claude.ai), [gemini.google.com](http://gemini.google.com), or [chatgpt.com](http://chatgpt.com) and ask it to adapt the code to your needs (in fact, I prompted this entire noscript over the course of a week...I didn't actually write it myself)
Setting up your own models will require another tutorial, but you can get started here:
* r/Oobabooga
* r/LMStudio
* r/LocalLLaMA
* r/LLMDevs
# How does it work?
Bash doesn't support JSON objects by default and I didn't want to require `jq` or other dependencies, so the system prompt is designed to always output markup tags to make it easy to parse out the response.
* Anything inside <bot>...</bot> is extracted and emitted into the terminal
* Anything inside <bash>...</bash> is actually interpreted by Bash line-by-line
# The Script
**Copy+paste the noscript below or clone from Github:** [https://github.com/ozfromscratch/chat](https://github.com/ozfromscratch/chat)
**🚨 BE CAREFUL: **This noscript acts on your behalf with all your permissions, it can even elevate your permissions
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CONFIG_FILE="$SCRIPT_DIR/chat.config"
HISTORY_FILE="$SCRIPT_DIR/chat.history"
LOG_FILE="$SCRIPT_DIR/chat.logs"
# System prompt as a variable for easy editing
SYSTEM_PROMPT="You are in a Linux Terminal. ALWAYS respond using <bot>response goes here</bot> markup. You MUST ALWAYS include executable bash noscripts within <bash>bash noscript here</bash> tags. NEVER use backticks for code, ALWAYS use <bash> tags as these will be parsed out and executed. When asked to create files etc, assume the current directory. Always escape quotes since you're in a terminal. REMEMBER: YOU MUST ALWAYS OUTPUT THE ACTUAL CODE IN <bash> TAGS, NOT JUST DESCRIBE IT. The content may be | piped...DO NOT output any extra content like 'Done!' or 'Ok' if there is code, just output the tags with the code so it can run. NEVER use > or < ALWAYS output the actual characters, escape with slash if needed"
# Function to load or prompt for configuration
load_or_prompt_config() {
if [ -f "$CONFIG_FILE" ]; then
source "$CONFIG_FILE"
fi
if [ -z "$OPENROUTER_API_KEY" ]; then
read -p "Enter your OpenRouter API key: " OPENROUTER_API_KEY >&2
echo "OPENROUTER_API_KEY='$OPENROUTER_API_KEY'" >> "$CONFIG_FILE"
fi
if [ -z "$OPENROUTER_MODEL" ]; then
read -p "Enter the OpenRouter model (e.g., openai/gpt-3.5-turbo): " OPENROUTER_MODEL >&2
echo "OPENROUTER_MODEL='$OPENROUTER_MODEL'" >> "$CONFIG_FILE"
fi
}
# Function to send message to OpenRouter API
send_message() {
local messages="$1"
local model="$2"
local response=$(curl -s "https://openrouter.ai/api/v1/chat/completions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer
https://preview.redd.it/yftl7f2l2whd1.png?width=1883&format=png&auto=webp&s=ca5bb1424ed22760fc71a6e8abb532dce91e88b7
# Integration with Unix tools
# Save output to a file
./chat "Write a short report on climate change" > climate_report.txt
# Count words in generated content
./chat "Write a haiku about the singularity" | tee >(wc -w)
# Process file contents
cat complicated_code.py | ./chat "Explain this Python code and suggest optimizations"
# Data analysis
cat large_dataset.csv | ./chat "Analyze this CSV data and provide insights"
https://preview.redd.it/gehidtqn3whd1.png?width=1378&format=png&auto=webp&s=4f099a8be45cc847d380014ddfa84d74923dc1e5
# What about offline or custom models?
This noscript was intentionally kept simple so you can adapt it to work with any server and model, including offline and self hosted ones
Almost all the leading Large Langauge Models are compatible with the OpenAI API, which is what this noscript is built around. If you have a custom setup, simply copy+paste the noscript into your favorite chatbot like [claude.ai](http://claude.ai), [gemini.google.com](http://gemini.google.com), or [chatgpt.com](http://chatgpt.com) and ask it to adapt the code to your needs (in fact, I prompted this entire noscript over the course of a week...I didn't actually write it myself)
Setting up your own models will require another tutorial, but you can get started here:
* r/Oobabooga
* r/LMStudio
* r/LocalLLaMA
* r/LLMDevs
# How does it work?
Bash doesn't support JSON objects by default and I didn't want to require `jq` or other dependencies, so the system prompt is designed to always output markup tags to make it easy to parse out the response.
* Anything inside <bot>...</bot> is extracted and emitted into the terminal
* Anything inside <bash>...</bash> is actually interpreted by Bash line-by-line
# The Script
**Copy+paste the noscript below or clone from Github:** [https://github.com/ozfromscratch/chat](https://github.com/ozfromscratch/chat)
**🚨 BE CAREFUL: **This noscript acts on your behalf with all your permissions, it can even elevate your permissions
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CONFIG_FILE="$SCRIPT_DIR/chat.config"
HISTORY_FILE="$SCRIPT_DIR/chat.history"
LOG_FILE="$SCRIPT_DIR/chat.logs"
# System prompt as a variable for easy editing
SYSTEM_PROMPT="You are in a Linux Terminal. ALWAYS respond using <bot>response goes here</bot> markup. You MUST ALWAYS include executable bash noscripts within <bash>bash noscript here</bash> tags. NEVER use backticks for code, ALWAYS use <bash> tags as these will be parsed out and executed. When asked to create files etc, assume the current directory. Always escape quotes since you're in a terminal. REMEMBER: YOU MUST ALWAYS OUTPUT THE ACTUAL CODE IN <bash> TAGS, NOT JUST DESCRIBE IT. The content may be | piped...DO NOT output any extra content like 'Done!' or 'Ok' if there is code, just output the tags with the code so it can run. NEVER use > or < ALWAYS output the actual characters, escape with slash if needed"
# Function to load or prompt for configuration
load_or_prompt_config() {
if [ -f "$CONFIG_FILE" ]; then
source "$CONFIG_FILE"
fi
if [ -z "$OPENROUTER_API_KEY" ]; then
read -p "Enter your OpenRouter API key: " OPENROUTER_API_KEY >&2
echo "OPENROUTER_API_KEY='$OPENROUTER_API_KEY'" >> "$CONFIG_FILE"
fi
if [ -z "$OPENROUTER_MODEL" ]; then
read -p "Enter the OpenRouter model (e.g., openai/gpt-3.5-turbo): " OPENROUTER_MODEL >&2
echo "OPENROUTER_MODEL='$OPENROUTER_MODEL'" >> "$CONFIG_FILE"
fi
}
# Function to send message to OpenRouter API
send_message() {
local messages="$1"
local model="$2"
local response=$(curl -s "https://openrouter.ai/api/v1/chat/completions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer
$OPENROUTER_API_KEY" \
-d '{
"model": "'"$model"'",
"messages": '"$messages"'
}')
echo "$response"
}
# Function to update history
update_history() {
local role="$1"
local content="$2"
echo "<$role>$content</$role>" >> "$HISTORY_FILE"
}
# Function to update logs
update_logs() {
local content="$1"
echo "$content" >> "$LOG_FILE"
}
# Function to clear history and logs
clear_history_and_logs() {
if [ -f "$HISTORY_FILE" ]; then
rm "$HISTORY_FILE"
echo "Chat history cleared." >&2
else
echo "No chat history found." >&2
fi
if [ -f "$LOG_FILE" ]; then
rm "$LOG_FILE"
echo "Chat logs cleared." >&2
else
echo "No chat logs found." >&2
fi
}
# Function to execute bash noscripts found in the response
execute_bash_noscripts() {
local response="$1"
local is_piped="$2"
if [ "$is_piped" = true ]; then
# If piped, only output the content of bash tags
echo "$response" | sed -n '/<bash>/,/<\/bash>/p' | sed 's/<bash>//g; s/<\/bash>//g'
else
echo "$response" # Output the entire response
# Extract and execute all bash noscripts
local in_bash=false
local bash_noscript=""
while IFS= read -r line; do
if [[ $line == *"<bash>"* ]]; then
in_bash=true
bash_noscript=""
elif [[ $line == *"</bash>"* ]]; then
in_bash=false
# Unescape quotes before execution for all bash commands
bash_noscript=$(echo "$bash_noscript" | sed 's/\\"/"/g')
eval "$bash_noscript"
elif $in_bash; then
bash_noscript+="$line"$'\n'
fi
done <<< "$response"
fi
}
# Main chat function
chat() {
local user_input="$1"
local model="$2"
local is_piped="$3"
# Load history if exists
if [ -f "$HISTORY_FILE" ]; then
history=$(cat "$HISTORY_FILE")
else
history=""
fi
# Prepare the messages for the API
local messages="["
messages+="{\"role\":\"system\",\"content\":\"<system>$SYSTEM_PROMPT</system>\"},"
while IFS= read -r line || [ -n "$line" ]; do
if [[ $line =~ \<user\>(.*)\</user\> ]]; then
messages+="{\"role\":\"user\",\"content\":\"<user>${BASH_REMATCH[1]}</user>\"},"
elif [[ $line =~ \<bot\>(.*)\</bot\> ]]; then
messages+="{\"role\":\"assistant\",\"content\":\"<bot>${BASH_REMATCH[1]}</bot>\"},"
fi
done <<< "$history"
messages+="{\"role\":\"user\",\"content\":\"<user>$user_input</user>\"}]"
# Send message and get response
local full_response=$(send_message "$messages" "$model")
# Log the raw server response
update_logs "$full_response"
# Extract the bot's response from the full server response
local bot_response=$(echo "$full_response" | sed -n 's/.*<bot>\(.*\)<\/bot>.*/\1/p' | sed 's/\\n/\n/g')
# Execute any bash noscripts found in the response and output other content
execute_bash_noscripts "$bot_response" "$is_piped"
# Update history with user input and assistant's response
update_history "user" "$user_input"
update_history "bot" "$bot_response"
}
# Load or prompt for configuration
load_or_prompt_config
# Initialize variables
clear_flag=false
model="$OPENROUTER_MODEL"
user_input=""
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
--clear)
clear_flag=true
shift
;;
--model)
-d '{
"model": "'"$model"'",
"messages": '"$messages"'
}')
echo "$response"
}
# Function to update history
update_history() {
local role="$1"
local content="$2"
echo "<$role>$content</$role>" >> "$HISTORY_FILE"
}
# Function to update logs
update_logs() {
local content="$1"
echo "$content" >> "$LOG_FILE"
}
# Function to clear history and logs
clear_history_and_logs() {
if [ -f "$HISTORY_FILE" ]; then
rm "$HISTORY_FILE"
echo "Chat history cleared." >&2
else
echo "No chat history found." >&2
fi
if [ -f "$LOG_FILE" ]; then
rm "$LOG_FILE"
echo "Chat logs cleared." >&2
else
echo "No chat logs found." >&2
fi
}
# Function to execute bash noscripts found in the response
execute_bash_noscripts() {
local response="$1"
local is_piped="$2"
if [ "$is_piped" = true ]; then
# If piped, only output the content of bash tags
echo "$response" | sed -n '/<bash>/,/<\/bash>/p' | sed 's/<bash>//g; s/<\/bash>//g'
else
echo "$response" # Output the entire response
# Extract and execute all bash noscripts
local in_bash=false
local bash_noscript=""
while IFS= read -r line; do
if [[ $line == *"<bash>"* ]]; then
in_bash=true
bash_noscript=""
elif [[ $line == *"</bash>"* ]]; then
in_bash=false
# Unescape quotes before execution for all bash commands
bash_noscript=$(echo "$bash_noscript" | sed 's/\\"/"/g')
eval "$bash_noscript"
elif $in_bash; then
bash_noscript+="$line"$'\n'
fi
done <<< "$response"
fi
}
# Main chat function
chat() {
local user_input="$1"
local model="$2"
local is_piped="$3"
# Load history if exists
if [ -f "$HISTORY_FILE" ]; then
history=$(cat "$HISTORY_FILE")
else
history=""
fi
# Prepare the messages for the API
local messages="["
messages+="{\"role\":\"system\",\"content\":\"<system>$SYSTEM_PROMPT</system>\"},"
while IFS= read -r line || [ -n "$line" ]; do
if [[ $line =~ \<user\>(.*)\</user\> ]]; then
messages+="{\"role\":\"user\",\"content\":\"<user>${BASH_REMATCH[1]}</user>\"},"
elif [[ $line =~ \<bot\>(.*)\</bot\> ]]; then
messages+="{\"role\":\"assistant\",\"content\":\"<bot>${BASH_REMATCH[1]}</bot>\"},"
fi
done <<< "$history"
messages+="{\"role\":\"user\",\"content\":\"<user>$user_input</user>\"}]"
# Send message and get response
local full_response=$(send_message "$messages" "$model")
# Log the raw server response
update_logs "$full_response"
# Extract the bot's response from the full server response
local bot_response=$(echo "$full_response" | sed -n 's/.*<bot>\(.*\)<\/bot>.*/\1/p' | sed 's/\\n/\n/g')
# Execute any bash noscripts found in the response and output other content
execute_bash_noscripts "$bot_response" "$is_piped"
# Update history with user input and assistant's response
update_history "user" "$user_input"
update_history "bot" "$bot_response"
}
# Load or prompt for configuration
load_or_prompt_config
# Initialize variables
clear_flag=false
model="$OPENROUTER_MODEL"
user_input=""
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
--clear)
clear_flag=true
shift
;;
--model)
model="$2"
shift 2
;;
*)
user_input+=" $1"
shift
;;
esac
done
# Check for --clear flag
if $clear_flag; then
clear_history_and_logs
exit 0
fi
# Run chat function with input from command line or pipe
if [ -p /dev/stdin ]; then
# Input is coming from a pipe
piped_input=$(cat)
if [ -n "$user_input" ]; then
chat "Context: $piped_input\n\nTask: $user_input" "$model" false
else
chat "$piped_input" "$model" false
fi
else
# Trim leading and trailing spaces from user input
user_input="${user_input#"${user_input%%[![:space:]]*}"}"
user_input="${user_input%"${user_input##*[![:space:]]}"}"
fi
if [ -z "$user_input" ]; then
echo "Usage: $0 [--clear] [--model MODEL] \"Your message here\"" >&2
echo " echo \"Your message here\" | $0 [--clear] [--model MODEL]" >&2
exit 1
fi
# Check if the noscript is being piped
if [ -p /dev/stdout ]; then
is_piped=true
else
is_piped=false
fi
chat "$user_input" "$model" "$is_piped"
https://redd.it/1ep1nkt
@r_bash
shift 2
;;
*)
user_input+=" $1"
shift
;;
esac
done
# Check for --clear flag
if $clear_flag; then
clear_history_and_logs
exit 0
fi
# Run chat function with input from command line or pipe
if [ -p /dev/stdin ]; then
# Input is coming from a pipe
piped_input=$(cat)
if [ -n "$user_input" ]; then
chat "Context: $piped_input\n\nTask: $user_input" "$model" false
else
chat "$piped_input" "$model" false
fi
else
# Trim leading and trailing spaces from user input
user_input="${user_input#"${user_input%%[![:space:]]*}"}"
user_input="${user_input%"${user_input##*[![:space:]]}"}"
fi
if [ -z "$user_input" ]; then
echo "Usage: $0 [--clear] [--model MODEL] \"Your message here\"" >&2
echo " echo \"Your message here\" | $0 [--clear] [--model MODEL]" >&2
exit 1
fi
# Check if the noscript is being piped
if [ -p /dev/stdout ]; then
is_piped=true
else
is_piped=false
fi
chat "$user_input" "$model" "$is_piped"
https://redd.it/1ep1nkt
@r_bash
Reddit
From the bash community on Reddit: ./chat - A minimal curl-based chatbot with ability to noscript and run code (tutorial && code)
Explore this post and more from the bash community
What’s your keyboard of choice ?
I like Topre switches but the Realforce I have is 100% size so I need to downsize to a 75%, but open to cherry mx style switches too.
What’s your keyboard of choice ?
https://redd.it/1ep32ni
@r_bash
I like Topre switches but the Realforce I have is 100% size so I need to downsize to a 75%, but open to cherry mx style switches too.
What’s your keyboard of choice ?
https://redd.it/1ep32ni
@r_bash
Reddit
From the bash community on Reddit
Explore this post and more from the bash community
How to detach running process from the terminal?
Hi! My task is to show a loading indicator for some application while it's being
launched (not when after it's started). To simulate some long running program
I've written this simple noscript:
To show a loading indicator I decided to use
But it doesn't work as I expect:
this code to make it solve the initial task?
More context: I need it because I am writing a terminal launcher for Flatpak
applications. The code is in another shell but I think that if I knew how to solve it in Bash I would be able to do it in Fish too.
https://redd.it/1ep5y62
@r_bash
Hi! My task is to show a loading indicator for some application while it's being
launched (not when after it's started). To simulate some long running program
I've written this simple noscript:
#!/usr/bin/env bash
sleep 10000s
To show a loading indicator I decided to use
gum spin {{command}}:gum spin -- bash -c './long_running_program.bash & disown $!'
But it doesn't work as I expect:
gum spin hangs out and waits. How to fixthis code to make it solve the initial task?
More context: I need it because I am writing a terminal launcher for Flatpak
applications. The code is in another shell but I think that if I knew how to solve it in Bash I would be able to do it in Fish too.
https://redd.it/1ep5y62
@r_bash
GitHub
desktop-environment/open-flatpak-application.fish at main · EmilyGraceSeville7cf/desktop-environment
Contribute to EmilyGraceSeville7cf/desktop-environment development by creating an account on GitHub.
Output alignment help.
I have been trying to get this alignment right. As you see the Disk Info section of the output doesnt align. Im close to just leaving it lol.
output is shown in the images tab. Heres the code snippet if you want to try:
# https://pastebin.com/P58YNAKX
https://redd.it/1epo07v
@r_bash
I have been trying to get this alignment right. As you see the Disk Info section of the output doesnt align. Im close to just leaving it lol.
output is shown in the images tab. Heres the code snippet if you want to try:
# https://pastebin.com/P58YNAKX
https://redd.it/1epo07v
@r_bash
Pastebin
# Function to get system identificationget_system_identification() { echo - Pastebin.com
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
Avoid cut words in long sentences
Using "cat" I often find myself having words cut off if the words are part of a sentence longer than the width of the terminal (on average 80 characters).
Is there a way to get a new line to the last blank space before the sentence reaches the edge of the window?
Thanks in advance.
EDIT: it seems that the command
I'd like to know your solutions instead.
https://redd.it/1eps3r5
@r_bash
Using "cat" I often find myself having words cut off if the words are part of a sentence longer than the width of the terminal (on average 80 characters).
Is there a way to get a new line to the last blank space before the sentence reaches the edge of the window?
Thanks in advance.
EDIT: it seems that the command
fold -sw 80 ./file did the trickI'd like to know your solutions instead.
https://redd.it/1eps3r5
@r_bash
Reddit
From the bash community on Reddit
Explore this post and more from the bash community
How to add shell command?
I am trying to learn assembly and constantly using nasm and then linking object file is really pissing me off, so I tried to make a bash function that will take the name of .asm file and do the thing, but my limited knowledge (nearly none) of shell noscripting did not allowed me to do this.
I made it like this and every time I am trying to run it a get:
Tell me what do I do wrong.
https://redd.it/1epufjb
@r_bash
I am trying to learn assembly and constantly using nasm and then linking object file is really pissing me off, so I tried to make a bash function that will take the name of .asm file and do the thing, but my limited knowledge (nearly none) of shell noscripting did not allowed me to do this.
function nasm64_asm() {object_name="middle_runner"argv1=$1run="run_it""nasm -f elf64 -o ${object_name}.o ${argv1}""ld ${object_name}.o -o ${run}"}export -f nasm64_asmI made it like this and every time I am trying to run it a get:
nasm64_asm learning_asm.asm ▦ Programming/assembly 22:13bash: nasm -f elf64 -o middle_runner.o learning_asm.asm: command not foundbash: ld middle_runner.o -o run_it: command not found[ble: exit 127]Tell me what do I do wrong.
https://redd.it/1epufjb
@r_bash
Reddit
From the bash community on Reddit
Explore this post and more from the bash community
What does peace of mind look like for a shell/Terminal layer software developer /programmer?
Asking for a brother who is building tools to help other shell/Terminal layer programmers. Thank you.
https://redd.it/1eq03uz
@r_bash
Asking for a brother who is building tools to help other shell/Terminal layer programmers. Thank you.
https://redd.it/1eq03uz
@r_bash
Reddit
From the bash community on Reddit
Explore this post and more from the bash community
Countdown timer demo with bash-boost
A few days back, I answered a question here on how to center colored text in a noscript which was a basic countdown timer.
While it seems simple on its face, I found it to be an interesting use case to explore some of the features of `bash-boost`.
I wrote about the interesting parts of the noscript here. A link to the full noscript is at the bottom of the README.
Hope you may find something useful from this walkthrough to use in your own noscripts. :)
https://redd.it/1eq6k6s
@r_bash
A few days back, I answered a question here on how to center colored text in a noscript which was a basic countdown timer.
While it seems simple on its face, I found it to be an interesting use case to explore some of the features of `bash-boost`.
I wrote about the interesting parts of the noscript here. A link to the full noscript is at the bottom of the README.
Hope you may find something useful from this walkthrough to use in your own noscripts. :)
https://redd.it/1eq6k6s
@r_bash
GitHub
GitHub - tomocafe/bash-boost: bash-boost is a set of library functions for bash, useful for both noscripting and interactive use.…
bash-boost is a set of library functions for bash, useful for both noscripting and interactive use. It draws inspiration from the Boost C++ libraries. - tomocafe/bash-boost
I need 2 MacOS Shell/zsh/bash(idk) noscripts, clean folders up, and paste new files into folders, willing to pay
Hi, I need 2 noscripts:
- a noscript to put all files of a folder into a "used" folder. I have 80 folders where this needs to get done, hence i need a noscript. There may already be a "used" folder, but if it does not exist yet, create it
- a noscript to paste 20 new files into all 30 folders
I found this https://discussions.apple.com/thread/253031808?sortBy=rank but it's not exactly what i need
Can someone help me? I'm willing to pay 🙏 And Yes you can share the noscript publicly, you can also put it on your GitHub of course. So maybe it will help others too
Maybe we should make a small MacOS App out of it? Idk if automator is enough for it. tbh i got 0 experience with automator
I have M1 macbook
Thank you so much!!!!❤️🙏🙏🙏❤️❤️
all folders have the same parent folder & source is in same place in a folder.
But i do the task for different folders and sources so i can’t solve this by hardcoding paths
What I want is a drag&drop solution, or a solution where the finder selection pops up and i have to select the files
I can’t do it by path cuz this is a weekly task with always different paths
https://redd.it/1eq7lih
@r_bash
Hi, I need 2 noscripts:
- a noscript to put all files of a folder into a "used" folder. I have 80 folders where this needs to get done, hence i need a noscript. There may already be a "used" folder, but if it does not exist yet, create it
- a noscript to paste 20 new files into all 30 folders
I found this https://discussions.apple.com/thread/253031808?sortBy=rank but it's not exactly what i need
Can someone help me? I'm willing to pay 🙏 And Yes you can share the noscript publicly, you can also put it on your GitHub of course. So maybe it will help others too
Maybe we should make a small MacOS App out of it? Idk if automator is enough for it. tbh i got 0 experience with automator
I have M1 macbook
Thank you so much!!!!❤️🙏🙏🙏❤️❤️
all folders have the same parent folder & source is in same place in a folder.
But i do the task for different folders and sources so i can’t solve this by hardcoding paths
What I want is a drag&drop solution, or a solution where the finder selection pops up and i have to select the files
I can’t do it by path cuz this is a weekly task with always different paths
https://redd.it/1eq7lih
@r_bash
Reddit
From the bash community on Reddit
Explore this post and more from the bash community
BashScripts v2.6.0: Turn off Monitors in Wayland, launch Chrome in pure Wayland, and much more.
https://github.com/hopeseekr/BashScripts/
https://redd.it/1eqbn3p
@r_bash
https://github.com/hopeseekr/BashScripts/
https://redd.it/1eqbn3p
@r_bash
GitHub
GitHub - hopeseekr/BashScripts: My own personal bash noscripts that revolutionize my life!!
My own personal bash noscripts that revolutionize my life!! - hopeseekr/BashScripts
How to restart a 'man' process?
I'm writing a troff manual, I want a process to watch for changes and compile and open it with 'man'.
But I'm having issues, I'm currently using this noscript :
inotifywait -q -m -e close_write --format %e ./test.man| while read events; do man ./test.man;done
The problem is that since man need to quit before the next change detection starts, I need to know a way to :
1 - watch for file change
2 - open the file using man (even if a man is already running)
Note : I want to replicate how I work with latex and mupdf, since all it takes is to restart a mupdf process is `pkill -HIP mupdf`
https://redd.it/1eqehuy
@r_bash
I'm writing a troff manual, I want a process to watch for changes and compile and open it with 'man'.
But I'm having issues, I'm currently using this noscript :
inotifywait -q -m -e close_write --format %e ./test.man| while read events; do man ./test.man;done
The problem is that since man need to quit before the next change detection starts, I need to know a way to :
1 - watch for file change
2 - open the file using man (even if a man is already running)
Note : I want to replicate how I work with latex and mupdf, since all it takes is to restart a mupdf process is `pkill -HIP mupdf`
https://redd.it/1eqehuy
@r_bash
Reddit
From the bash community on Reddit
Explore this post and more from the bash community
Is it possible to export a bash function so that it will automatically enable extglob?
I have a bash function that uses some extglob which, if used in a shell with extglob disabled, fails to parse and throws a syntax error.
In the file containing the function source code I include a
shopt -s extglob
before the function is defined so that when the file is sourced extglob is enabled before the function is defined. But, if you export the function you only get the function, not the stuff before it. And any new bash shells will try and source the exported functions on startup.
In practice, this means that if I export my function, any future invocations of `/usr/bin/bash` that dont include `-O extglob` will print an error message to screen. This happens regardless if the bash shell being started is actually calling the exported function. It still runs if that exported function isnt used (since the error is that it cant parse the function), but is annoying nonetheless.
One specific annoyance with this that I use hyperfine to benchmark this function. the way hyperfine bootstraps the shells it runs, you can either use `--shell=bash` and itll use exported functions but wont have extglob, or you can use `--shell='/usr/bin/bash -O extglob'` to get extglob but you lose access to exported functions. You can use the ladder and then source the file defining the function and then run a the function, but then it skews the benchmarking times since you are timing how long it takes to source the function as well as timing the function runtime itself.
***
At any rate, does anyone know a trick so that exported functions that use extglob will parse correctly in a bash shell that doesnt explcitly enable extglob by being spawned via `bash -O extglob [...]`???
https://redd.it/1eqfzag
@r_bash
I have a bash function that uses some extglob which, if used in a shell with extglob disabled, fails to parse and throws a syntax error.
In the file containing the function source code I include a
shopt -s extglob
before the function is defined so that when the file is sourced extglob is enabled before the function is defined. But, if you export the function you only get the function, not the stuff before it. And any new bash shells will try and source the exported functions on startup.
In practice, this means that if I export my function, any future invocations of `/usr/bin/bash` that dont include `-O extglob` will print an error message to screen. This happens regardless if the bash shell being started is actually calling the exported function. It still runs if that exported function isnt used (since the error is that it cant parse the function), but is annoying nonetheless.
One specific annoyance with this that I use hyperfine to benchmark this function. the way hyperfine bootstraps the shells it runs, you can either use `--shell=bash` and itll use exported functions but wont have extglob, or you can use `--shell='/usr/bin/bash -O extglob'` to get extglob but you lose access to exported functions. You can use the ladder and then source the file defining the function and then run a the function, but then it skews the benchmarking times since you are timing how long it takes to source the function as well as timing the function runtime itself.
***
At any rate, does anyone know a trick so that exported functions that use extglob will parse correctly in a bash shell that doesnt explcitly enable extglob by being spawned via `bash -O extglob [...]`???
https://redd.it/1eqfzag
@r_bash
Reddit
From the bash community on Reddit
Explore this post and more from the bash community
Formatting and mounting a flash drive via the terminal, not the UI
I'm issuing the following commands to format a 512GB flash drive:
The output from the last command indicates that the flash drive was successfully formatted. How can I mount that device w/o having to select the device in the file explorer? I'd like to accomplish this using only the terminal.
https://redd.it/1eqgrco
@r_bash
I'm issuing the following commands to format a 512GB flash drive:
sudo fdisk -l # fetch device ID (/dev/sdc1)sudo umount /dev/sdc1sudo mkfs.exfat -n USB-256GB /dev/sdc1The output from the last command indicates that the flash drive was successfully formatted. How can I mount that device w/o having to select the device in the file explorer? I'd like to accomplish this using only the terminal.
https://redd.it/1eqgrco
@r_bash
Reddit
From the bash community on Reddit
Explore this post and more from the bash community
argc - Top-tier utility/framework for creating shell noscripts
https://github.com/sigoden/argc
I’m not the author. Whoever it is, they are a bloody legend!
Figured I would share it as it deserves way more love.
https://redd.it/1eqvgj4
@r_bash
https://github.com/sigoden/argc
I’m not the author. Whoever it is, they are a bloody legend!
Figured I would share it as it deserves way more love.
https://redd.it/1eqvgj4
@r_bash
GitHub
GitHub - sigoden/argc: A Bash CLI framework, also a Bash command runner.
A Bash CLI framework, also a Bash command runner. Contribute to sigoden/argc development by creating an account on GitHub.
How to learn shell noscripting?
I have basic / intermediate knowledge of command line and would like to learn how to use shell noscripting. Are there websites or resources that provide problems that I can try and solve? I am also interested in shell noscripts for HPC so I was wondering what area I should focus on here.
https://redd.it/1erft7a
@r_bash
I have basic / intermediate knowledge of command line and would like to learn how to use shell noscripting. Are there websites or resources that provide problems that I can try and solve? I am also interested in shell noscripts for HPC so I was wondering what area I should focus on here.
https://redd.it/1erft7a
@r_bash
Reddit
From the bash community on Reddit
Explore this post and more from the bash community
What does - and -- mean in bash?
I've come across noscripts that use - or -- for arguments and it's never really explained what they do. What's it called and what's the usage?
https://redd.it/1erzyy6
@r_bash
I've come across noscripts that use - or -- for arguments and it's never really explained what they do. What's it called and what's the usage?
# example using -
curl -fsSL 'some_url/install.sh' | env ENV="${HOME}/.bashrc" bash -
# example using --
command -- arg1 arg2
https://redd.it/1erzyy6
@r_bash
Reddit
From the bash community on Reddit
Explore this post and more from the bash community
Using read -p to prompt bold variable with ANSI escape codes?
Hi,\
As the noscript, I was wondering if it is possible to do it.\
I've tried 1
The output is what I desired, candy and yes are bold.\
I've tried 2
It output $var, not candy,\
\
I'd like something similar to second options, that way I can easily make a new line using '\n'. 3\
Is there any better solution? Or better using
~~I mean
https://redd.it/1es3gp5
@r_bash
Hi,\
As the noscript, I was wondering if it is possible to do it.\
I've tried 1
var=candy
bold=$(tput bold)
normal=$(tput sgr0)
read -p "IS ${bold}$var${normal} correct? " ans
# assuming answer yes
printf "Your answer is \033[1m%s\033[0m." "$ans"
The output is what I desired, candy and yes are bold.\
I've tried 2
var=candy
read -rep $'Is \033[1m$var\033[0m correct?' ans
printf "Your answer is \033[1m%s\033[0m." "$ans"
It output $var, not candy,\
\
I'd like something similar to second options, that way I can easily make a new line using '\n'. 3\
Is there any better solution? Or better using
printf and read separately. Something likeprintf "Is \033[1m%s\033[0m correct?" "$var"
read ans
printf "Your answer is \033[1m%s\033[0m." "$ans"
~~I mean
read -p is not supported in every shell, maybe it's a good habit to not use -p.~~https://redd.it/1es3gp5
@r_bash
Stack Overflow
How does one output bold text in Bash?
I'm writing a Bash noscript that prints some text to the screen:
echo "Some Text"
Can I format the text? I would like to make it bold.
echo "Some Text"
Can I format the text? I would like to make it bold.