Scripts
Overview
Section titled “Overview”A custom entry can run an inline script instead of starting a program directly. Scripts are useful for:
- Running shell commands
- Executing Python/Ruby/Perl code
- Chaining multiple commands
- Setting up environments before launching applications
Script Configuration
Section titled “Script Configuration”script string (required)
Inline script content. Can be a single line or multi-line string.
The script is executed using the interpreter specified in binary (or the default script shell).
binary string
Script interpreter. Defaults to bash (or the value set via --default-script-shell or general.default_script_shell).
Common values:
bash(default)python3rubyperl/bin/zsh
args array
Arguments passed to the script (not the interpreter).
These are available as $1, $2, etc. in shell scripts or sys.argv in Python.
env map of strings
Environment variables for the script, on top of Raffi’s own. See env on launcher entries.
Bash Scripts
Section titled “Bash Scripts”Single-Line Script
Section titled “Single-Line Script”hello_script: script: "echo 'Hello, World!'" description: "Hello Script" icon: "script"Multi-Line Script
Section titled “Multi-Line Script”hello_script: script: | echo "hello world and show me your env" env description: "Hello Script" icon: "script"Script with Arguments
Section titled “Script with Arguments”backup_script: script: | SOURCE=$1 DEST=$2 rsync -av "$SOURCE" "$DEST" notify-send "Backup complete" "$SOURCE → $DEST" args: ["~/Documents", "~/Backups"] description: "Backup Documents" icon: "backup"Python Scripts
Section titled “Python Scripts”Basic Python Script
Section titled “Basic Python Script”hello_python: binary: python3 script: | import os print("hello world and show me your env") print(os.environ) description: "Hello Python script" icon: "python"Python Script with Arguments
Section titled “Python Script with Arguments”process_data: binary: python3 script: | import sys import json
input_file = sys.argv[1] with open(input_file) as f: data = json.load(f)
print(f"Processed {len(data)} records") args: ["~/data/input.json"] description: "Process Data" icon: "python"Custom Interpreters
Section titled “Custom Interpreters”Ruby Script
Section titled “Ruby Script”ruby_script: binary: ruby script: | puts "Hello from Ruby!" puts "Ruby version: #{RUBY_VERSION}" description: "Ruby Hello" icon: "ruby"Perl Script
Section titled “Perl Script”perl_script: binary: perl script: | print "Hello from Perl!\n"; print "Perl version: $^V\n"; description: "Perl Hello" icon: "perl"Zsh Script
Section titled “Zsh Script”zsh_script: binary: /bin/zsh script: | echo "Hello from Zsh!" echo "Zsh version: $ZSH_VERSION" description: "Zsh Hello" icon: "terminal"Default Script Shell
Section titled “Default Script Shell”Set a default interpreter for all scripts:
Via Configuration
Section titled “Via Configuration”version: 1
general: default_script_shell: /bin/zshmy_script: script: "echo 'This runs with zsh'" description: "My Script"Via Command Line
Section titled “Via Command Line”raffi --default-script-shell /bin/zshScript Execution
Section titled “Script Execution”When an entry with a script field is selected:
- Raffi checks if the interpreter exists in PATH
- The script is executed as:
<interpreter> -c "<script>" - If
argsare present, they’re passed to the script (not the interpreter)
Print-Only Mode
Section titled “Print-Only Mode”To see the exact command without executing:
raffi --print-onlyFor a script entry, this outputs a shell-ready command line:
env -- bash -c 'echo "hello world and show me your env"env'Quoting is preserved, so the output can be evaluated directly with sh -c "$cmd" or handed to a
compositor as a single argument. A multi-line script stays multi-line inside the quotes; do not pipe
it through xargs, which strips the quotes.
Real-World Examples
Section titled “Real-World Examples”Password Generator
Section titled “Password Generator”passgen: binary: kitty-ctrl args: ["jump", "-t", "GeneratePassword", "genpasswd"] description: "Password Generator" icon: passwordSystem Monitoring
Section titled “System Monitoring”bpytop: binary: kitty-ctrl args: ["jump", "bpytop"] description: "BpyTOP" icon: bashtop ifexist: bpytopCustom Window Management
Section titled “Custom Window Management”center-window: binary: wmctrl-resize-and-center description: "Center window" icon: wmsnap
snap-window-around: binary: wmctrl-resize-and-center args: [rotate] description: "Snap window around" icon: wmaround ifenveq: [XDG_SESSION_TYPE, x11]Path Expansion in Scripts
Section titled “Path Expansion in Scripts”If you need path expansion in scripts, do it explicitly:
backup: script: | HOME=$HOME SOURCE="$HOME/Documents" DEST="$HOME/Backups" rsync -av "$SOURCE" "$DEST" description: "Backup"Or use arguments with expansion:
backup: script: | rsync -av "$1" "$2" args: ["~/Documents", "~/Backups"] description: "Backup"Validation
Section titled “Validation”Script entries are validated on startup:
- Interpreter check: The
binary(or default shell) must exist in PATH - Conditional checks: If
ifexist,ifenvset, orifenveqare present, they must pass - Disabled check: If
disabled: true, the entry is hidden
If validation fails, the entry is hidden from the list.