#!/bin/bash set -e set -f set -o pipefail shopt -s lastpipe BOT_SIZE=8 BOT_TITLE=input BOT_CMD='PS1="$BOT_TITLE\$ " bash --noprofile --norc -i' TOP_CMD='PS1="$TOP_TITLE\$ " bash --noprofile --norc -i' TOP_TITLE=output TWOPANE=$(mktemp -d) export TWOPANE TOP_CMD BOT_CMD TOP_TITLE BOT_TITLE BOT_SIZE trap 'rm -r "$TWOPANE"' EXIT STY=twopane.${TWOPANE##*/} cat > "$TWOPANE"/screenrc <<'.' unbindall escape \0\0 caption string '%t' layout new split focus bottom resize $BOT_SIZE screen -ln -t "$BOT_TITLE" 0 bash "$TWOPANE"/bashrc source "$TWOPANE"/screenrc.startpane . cat > "$TWOPANE"/screenrc.startpane <<'.' focus top screen -ln -t "$TOP_TITLE" 1 sh -c "$TOP_CMD; screen -X focus top; screen -X remove" exec :!:| socat -u UNIX-RECV:"$TWOPANE"/socket STDOUT title 'output' focus bottom layout save 0 . cat > "$TWOPANE"/screenrc.restart <<'.' layout new split focus bottom resize $BOT_SIZE select 0 title 'input' source "$TWOPANE"/screenrc.startpane . cat > "$TWOPANE"/bashrc <<'.' trap "screen -X quit" EXIT restart() { screen -X source "$TWOPANE"/screenrc.restart } sendp() { socat -U UNIX-SENDTO:"$TWOPANE"/socket STDIN } sendc() { printf '%s' "$*" | sendp } send() { sendc "$*"$'\n' } export -f send sendc sendp restart bash -c "$BOT_CMD" || read -p "Error: process terminated with exit code $? Press enter to quit." . screen -c "$TWOPANE"/screenrc -m -S "$STY" -ln