-
Notifications
You must be signed in to change notification settings - Fork 9
Shell Scripts
bkmr provides powerful shell script management with interactive execution, argument passing, and direct shell integration.
Shell scripts in bkmr are bookmarks with the _shell_
system tag that execute in your terminal. They support:
- Interactive editing before execution (default)
-
Direct execution with
--no-edit
flag -
Argument passing via
--
separator - Shell function stubs for direct command-line access
- Vim/Emacs bindings in interactive mode
- Command history for reuse
The default behavior presents an interactive editor before execution:
# Search and execute shell script
bkmr search --fzf -t _shell_
# Or open by ID
bkmr open 123
Interactive editor features:
- Pre-filled with script content
- Full editing capabilities (modify, add parameters, combine commands)
- Vim or Emacs bindings based on your shell configuration
- Command history saved to
~/.config/bkmr/shell_history.txt
- Press Enter to execute, Ctrl-C to cancel
Automatic binding detection:
- Checks
$ZSH_VI_MODE
for zsh vi mode - Reads
.inputrc
for readline settings - Detects
set -o vi
/set -o emacs
in bash - Defaults to emacs bindings
Skip the interactive editor and execute immediately:
# Direct execution without editing
bkmr open --no-edit 123
# Useful in automation or when script is trusted
bkmr open --no-edit <id>
Pass arguments to scripts using the --
separator:
# Arguments passed as $1, $2, $3, etc.
bkmr open --no-edit 123 -- arg1 arg2 arg3
# Real-world example: deployment script
bkmr open --no-edit 456 -- --env production --dry-run
# In your script, access with:
#!/bin/bash
echo "Environment: $1" # --env
echo "Second arg: $2" # production
echo "Third arg: $3" # --dry-run
echo "All args: $@"
bkmr search --shell-stubs
(NOT bkmr create-shell-stubs
)
Shell function stubs transform your bookmarked shell scripts into callable shell functions, enabling natural command-line execution with full argument support.
# View all shell function stubs that would be created
bkmr search --shell-stubs
# Example output:
# backup-database() { bkmr open --no-edit 123 -- "$@"; }
# export -f backup-database
# deploy-app() { bkmr open --no-edit 124 -- "$@"; }
# export -f deploy-app
# monitoring-setup() { bkmr open --no-edit 125 -- "$@"; }
# export -f monitoring-setup
# Source directly into current shell - always fresh
source <(bkmr search --shell-stubs)
# Add to your shell profile for automatic loading
echo 'source <(bkmr search --shell-stubs)' >> ~/.bashrc
echo 'source <(bkmr search --shell-stubs)' >> ~/.zshrc
Benefits:
- Always reflects current bookmarks
- Automatically includes new shell script bookmarks
- No maintenance required
Considerations:
- Small startup delay (typically <100ms)
- Requires bkmr to be available in PATH
# Generate static functions file
bkmr search --shell-stubs > ~/.config/bkmr/shell-functions.sh
# Source the cached file in your profile
echo 'source ~/.config/bkmr/shell-functions.sh' >> ~/.bashrc
# Update when you add new shell script bookmarks
alias update-shell-stubs='bkmr search --shell-stubs > ~/.config/bkmr/shell-functions.sh'
Benefits:
- Faster shell startup
- Works without bkmr in PATH
- Explicit control over updates
Considerations:
- Manual refresh needed when bookmarks change
- Potential for stale functions
# Create functions only for specific tags
source <(bkmr search --tags _shell_,development --shell-stubs)
# Combine with tag filtering
source <(bkmr search --tags _shell_,production --shell-stubs)
# Prefix all functions to avoid conflicts
bkmr search --shell-stubs | sed 's/^/bkmr_/' > ~/.config/bkmr/namespaced-functions.sh
# Creates: bkmr_backup-database(), bkmr_deploy-app(), etc.
source ~/.config/bkmr/namespaced-functions.sh
# Create project-specific shell stub files
project-stubs() {
local project="$1"
bkmr search --tags _shell_,"$project" --shell-stubs > ".${project}-stubs.sh"
echo "Created .${project}-stubs.sh - source it with: source .${project}-stubs.sh"
}
# Usage
project-stubs myapp
source .myapp-stubs.sh
# Now use project-specific commands
myapp-deploy staging
myapp-backup production
# Add to ~/.bashrc or ~/.zshrc
source <(bkmr search --shell-stubs)
# Now your bookmarked scripts become part of your shell environment:
backup-database production --incremental
deploy-microservice user-auth staging --canary-percentage 10
scale-cluster monitoring --nodes 5
update-certificates *.example.com --dry-run
# All with full argument support and tab completion (if configured)
# Create deployment workflow using multiple script stubs
deploy-full() {
local env="${1:-staging}"
echo "Running full deployment to $env..."
backup-database "$env"
run-tests "$env"
deploy-application "$env"
verify-deployment "$env"
}
# All functions are generated from bookmarked shell scripts
The bkmr search --shell-stubs
command follows these naming rules:
-
Preserves hyphens:
"backup-database"
→backup-database()
-
Converts spaces to underscores:
"Deploy Script"
→deploy_script()
-
Handles special characters:
"My Awesome Script!"
→my_awesome_script()
-
Prevents numeric start:
"2fa-setup"
→script-2fa-setup()
-
Fallback for invalid names:
"!@#$%"
→shell_script()
Examples:
# Bookmark Title → Function Name
"Database Backup" → database_backup()
"deploy-to-production" → deploy-to-production()
"Run Tests (CI)" → run_tests_ci()
"2fa-setup" → script-2fa-setup()
1. Use Descriptive Bookmark Titles:
# Good: Clear, concise titles become readable functions
bkmr add "script content" ops,_shell_ --title "backup-database"
bkmr add "script content" deploy,_shell_ --title "deploy-to-production"
# Avoid: Generic or unclear titles
bkmr add "script content" ops,_shell_ --title "script1"
bkmr add "script content" deploy,_shell_ --title "do-stuff"
2. Tag Consistently:
# Use consistent tags for filtering
bkmr add "script" production,database,_shell_ --title "db-backup"
bkmr add "script" production,app,_shell_ --title "app-deploy"
# Generate only production scripts
source <(bkmr search --tags _shell_,production --shell-stubs)
3. Test Function Names:
# Preview function names before sourcing
bkmr search --shell-stubs | grep '^[a-zA-Z]' | cut -d'(' -f1
# Check for conflicts with existing commands
bkmr search --shell-stubs | grep '^[a-zA-Z]' | cut -d'(' -f1 | \
while read func; do type "$func" 2>&1 | grep -q "is a" && echo "Conflict: $func"; done
4. Document Complex Functions:
# Add comments in your shell profile
# bkmr shell function stubs - auto-generated
source <(bkmr search --shell-stubs)
# Usage: backup-database [environment] [--incremental]
# Usage: deploy-app [service-name] [environment]
5. Regular Cleanup:
# Periodically review shell script bookmarks
bkmr search --tags _shell_ --json | jq -r '.[] | "\(.id): \(.title)"'
# Remove unused scripts
bkmr delete <id>
# Check for conflicts before sourcing
bkmr search --shell-stubs | grep '^[a-zA-Z]' | cut -d'(' -f1 | sort | uniq -d
# Resolution strategies:
# 1. Rename conflicting bookmarks
# 2. Use namespacing (prefix with "bkmr_")
# 3. Use selective loading with tag filters
# Profile shell startup time
time (source <(bkmr search --shell-stubs))
# If too slow, switch to static caching
bkmr search --shell-stubs > ~/.config/bkmr/shell-functions.sh
# Then source the cached file in your profile
# Verify shell script bookmarks exist
bkmr search --tags _shell_ --json | jq length
# Check specific bookmark has _shell_ tag
bkmr show <id> | grep "_shell_"
# Verify functions are properly exported
declare -F | grep -E "(backup|deploy|monitoring)"
# Via environment variable
export BKMR_SHELL_INTERACTIVE=false
# Or in ~/.config/bkmr/config.toml
[shell_opts]
interactive = false
With interactive mode disabled, bkmr open <id>
executes directly without the editor.
All executed commands (from interactive mode) are saved to:
~/.config/bkmr/shell_history.txt
This provides a record of executed scripts for auditing or reuse.
# Add a deployment script
bkmr add "#!/bin/bash
echo 'Deploying application...'
ssh server 'cd /app && git pull && systemctl restart app'
" deploy,production,_shell_ --title "deploy-production"
# Execute with interactive editing
bkmr search --fzf -t _shell_,deploy
# Execute directly
bkmr open --no-edit <id>
# Execute with parameters
bkmr open --no-edit <id> -- --dry-run --verbose
# Create a parameterized backup script
bkmr add '#!/bin/bash
ENV=$1
INCREMENTAL=$2
if [[ "$INCREMENTAL" == "--incremental" ]]; then
echo "Running incremental backup for $ENV"
pg_dump -h "$ENV-db" myapp | gzip > "backup-$ENV-$(date +%Y%m%d)-incr.sql.gz"
else
echo "Running full backup for $ENV"
pg_dump -h "$ENV-db" myapp | gzip > "backup-$ENV-$(date +%Y%m%d)-full.sql.gz"
fi
' database,backup,_shell_ --title "backup-database"
# Use via shell stub
source <(bkmr search --shell-stubs)
backup-database production --incremental
backup-database staging
# Add environment-aware script
bkmr add '#!/bin/bash
ENV=${1:-staging}
case $ENV in
production)
echo "Deploying to PRODUCTION"
DEPLOY_HOST="prod.example.com"
;;
staging)
echo "Deploying to STAGING"
DEPLOY_HOST="staging.example.com"
;;
*)
echo "Unknown environment: $ENV"
exit 1
;;
esac
ssh "$DEPLOY_HOST" "cd /app && git pull && systemctl restart app"
' deploy,_shell_ --title "deploy-environment-aware"
# Execute with environment
bkmr open --no-edit <id> -- production
bkmr open --no-edit <id> -- staging
- Content Types - Shell script content type details
- Configuration - Shell execution configuration
- Advanced Workflows - Automation patterns
- Search and Discovery - Finding shell scripts
- Basic Usage - Common shell script commands