Files
config/tmux-oneshot.sh

110 lines
3.2 KiB
Bash

#!/bin/bash
# tmux-oneshot.sh
# Run a single command in a tmux session
# Built-in prompt patterns (command_pattern:prompt_pattern:timeout_seconds)
PROMPT_PATTERNS=(
"ssh*:Password|password:5"
"sudo*:Password|password|\\[sudo\\] password for:5"
"su*:Password|password:5"
"mysql*:Enter password:3"
"docker*:Password:2"
)
# Generic function to wait for prompts based on command patterns
wait_for_prompt() {
local cmd="$1"
# Find matching pattern for this command
for pattern in "${PROMPT_PATTERNS[@]}"; do
IFS=':' read -r cmd_pattern prompt_pattern timeout <<< "$pattern"
if [[ "$cmd" == $cmd_pattern ]]; then
echo "Waiting for prompt: $prompt_pattern (timeout: ${timeout}s)"
timeout=$((timeout * 10)) # Convert to 0.1s intervals
while [ $timeout -gt 0 ] && ! tmux capture-pane -t $SESSION -p | tail -3 | grep -E "($prompt_pattern)" >/dev/null 2>&1; do
sleep 0.1
timeout=$((timeout - 1))
done
if [ $timeout -eq 0 ]; then
echo "Timeout waiting for prompt: $prompt_pattern"
fi
return
fi
done
# No pattern matched, brief pause
sleep 0.5
}
# Load config file if it exists
SCRIPT_DIR=$(dirname "$0")
SCRIPT_NAME=$(basename "$0" .sh)
CONFIG_FILE="${SCRIPT_DIR}/${SCRIPT_NAME}.conf"
if [ -f "$CONFIG_FILE" ]; then
echo "Loading config from $CONFIG_FILE"
source "$CONFIG_FILE"
else
echo "Config file $CONFIG_FILE not found, generating template..."
cat > "$CONFIG_FILE" << 'EOF'
# tmux-oneshot.conf
# Configuration file for tmux-oneshot.sh
# Session name (leave empty to use first word of command)
SESSION=""
# For multiple commands, use an array:
# COMMANDS=("ssh root@server" "sudo su" "password123")
COMMANDS=()
# Whether to attach to session after running command (0 or 1)
ATTACH_SESSION=0
EOF
echo "Generated $CONFIG_FILE with default values. Please edit and run again."
exit 0
fi
# Validate required variables
if [ -z "$SESSION" ] && [ ${#COMMANDS[@]} -eq 0 ]; then
echo "Error: Either SESSION or COMMANDS must be set in $CONFIG_FILE" >&2
exit 1
fi
# Use command line arguments if provided, otherwise use config
if [ $# -gt 0 ]; then
COMMANDS=("$*")
echo "Using command line arguments: $*"
else
if [ ${#COMMANDS[@]} -eq 0 ]; then
echo "Error: No commands provided and no commands set in config" >&2
exit 1
fi
echo "Using config commands: ${COMMANDS[*]}"
fi
# Use session name from config, or first word of first command if not set
if [ -z "$SESSION" ]; then
SESSION=$(echo "${COMMANDS[0]}" | awk '{print $1}')
fi
# Create session if missing
if ! tmux has-session -t $SESSION 2>/dev/null; then
echo "Creating tmux session: $SESSION"
tmux new-session -d -s $SESSION
else
echo "Session $SESSION exists, reusing..."
fi
# Send commands individually with proper timing
echo "Running commands: ${COMMANDS[*]}"
for cmd in "${COMMANDS[@]}"; do
echo "Running: $cmd"
tmux send-keys -t $SESSION "$cmd" C-m
# Wait for command to complete or prompt for input with timeout
wait_for_prompt "$cmd"
done
if [ $ATTACH_SESSION -eq 1 ]; then
echo "Attaching to tmux session: $SESSION"
tmux attach -t $SESSION
fi