113 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
			
		
		
	
	
			113 lines
		
	
	
		
			3.4 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 i in "${!COMMANDS[@]}"; do
 | |
|     cmd="${COMMANDS[$i]}"
 | |
|     echo "Running: $cmd"
 | |
|     tmux send-keys -t $SESSION "$cmd" C-m
 | |
|     # Only wait if there is a subsequent command
 | |
|     if [ $i -lt $((${#COMMANDS[@]} - 1)) ]; then
 | |
|         # Wait for command to complete or prompt for input with timeout
 | |
|         wait_for_prompt "$cmd"
 | |
|     fi
 | |
| done
 | |
| 
 | |
| if [ $ATTACH_SESSION -eq 1 ]; then
 | |
|     echo "Attaching to tmux session: $SESSION"
 | |
|     tmux attach -t $SESSION
 | |
| fi |