-
Notifications
You must be signed in to change notification settings - Fork 2
/
wrap.sh
executable file
·130 lines (97 loc) · 2.89 KB
/
wrap.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#!/usr/bin/env bash
#
#/ Runs <command> in detached `tmux` <session>, while capturing output to <logfile>.
#/
#/ Usage:
#/ wrap <command> [<session>] [<logfile>]
#
set -euo pipefail
_usage() {
grep ^#/ "$0" | cut -c4-
exit
}
_error() {
echo >&2 "ERROR: ${1:-unknown error}"
exit 1
}
_confirm () {
read -r -p "${1:-Are you sure? [y/N]} " response
case $response in
[yY][eE][sS]|[yY]) true ;;
*) false ;;
esac
}
_tail_logs() {
echo "Tailing logs from '${TMUX_LOG}' file ..."
tail -f "${TMUX_LOG}"
}
_trap_cancel() {
echo >&2
echo >&2 "Aborted..."
exit 1
}
_trap_success() {
local filename
filename=$(printf "%q" "${TMUX_LOG}")
echo
echo "Log still could be accessible via:"
echo " \$ tail -f ${filename}"
echo " \$ less ${filename}"
exit
}
trap '_trap_cancel' SIGHUP SIGINT SIGQUIT SIGTERM
# prequisites
for cmd in tmux openssl cat tail time date xargs; do
hash "${cmd}" 2>/dev/null || _error "I require '${cmd}', but it's not installed"
done
TMUX_CMD="$(echo "${1:-}" | xargs)"
TMUX_SID="$(echo "${2:-wrap}" | xargs)"
TMUX_LOG="$(echo "${3:-"wrap.log.$(echo -n "${TMUX_CMD}" | openssl sha1)"}" | xargs)"
[[ "${TMUX_CMD}" == "--help" || "${TMUX_CMD}" == '-h' ]] && _usage
TMUX_CMD="$(sed 's/;\+$//' <<< "${TMUX_CMD}")"
[[ -z "${TMUX_CMD}" ]] && _error "command could not be empty"
# unset TMUX, due warning of nested session
# is there nicer solution?
unset TMUX
# has active session?
if tmux has -t "${TMUX_SID}" 2>/dev/null; then
trap - SIGHUP SIGINT SIGQUIT SIGTERM
trap '_trap_success' EXIT
tmux attach -t "${TMUX_SID}"
if tmux has -t "${TMUX_SID}" 2>/dev/null; then
_tail_logs
fi
echo "Session '${TMUX_SID}' has finished ..." | tee -a "${TMUX_LOG}"
exit
fi
echo "wrap - run command smart in tmux"
echo
echo " >> ${TMUX_CMD} << "
echo
if ! _confirm "Proceed? [y/N]"; then
echo "Aborted..." 2>&1
exit 1
fi
# wrap input command
TMUX_WRAP_CMD=$(cat <<==END
_log() { echo "> \$(date -u +"%F %T") \$1"; }
_log "Running: ${TMUX_CMD} "
set -x
time { ${TMUX_CMD}; }
{ retVal=\$?; set +x; echo; } 2>/dev/null
_log "Finished (exit \${retVal})"
==END
)
mkdir -p "$(dirname "${TMUX_LOG}")"
echo "Session '${TMUX_SID}' is starting ..." > "${TMUX_LOG}"
tmux new -d -s "${TMUX_SID}" -n "${TMUX_CMD}" "{ ${TMUX_WRAP_CMD}; } 2>&1 | tee -a '${TMUX_LOG}'"
tmux set -q -t "${TMUX_SID}" -g window-status-current-format "#[fg=colour0,bg=colour39] #W #[fg=colour39,bg=colour0]"
tmux set -q -t "${TMUX_SID}" -g status-bg colour3
tmux set -q -t "${TMUX_SID}" -g status-fg colour0
tmux set -q -t "${TMUX_SID}" -g status-left-length 50
tmux set -q -t "${TMUX_SID}" -g status-right-length 50
tmux set -q -t "${TMUX_SID}" -g status-right ' %Y-%m-%d %H:%M:%S '
tmux set -q -t "${TMUX_SID}" -g status-interval 1
trap - SIGHUP SIGINT SIGQUIT SIGTERM
trap '_trap_success' EXIT
_tail_logs