Skip to content

Instantly share code, notes, and snippets.

@jdavidrcamacho
Last active January 8, 2026 10:21
Show Gist options
  • Select an option

  • Save jdavidrcamacho/47f58cfbae40c38cd6d2a3638266cfa3 to your computer and use it in GitHub Desktop.

Select an option

Save jdavidrcamacho/47f58cfbae40c38cd6d2a3638266cfa3 to your computer and use it in GitHub Desktop.
To add to /etc/bash.bashrc
#########################################
if [ -n "$PS1" ]; then
# Commands logger
if [ -z "$BASH_COMMAND_LOGGER_SET" ]; then
export BASH_COMMAND_LOGGER_SET=1
shopt -s histappend
export HISTTIMEFORMAT="%F %T "
CMD_LOG_FILE="/var/log/commands.log"
LOG_HOST="$(hostname)"
LOG_IP="$(hostname -I 2>/dev/null | awk '{print $1}')"
PROMPT_COMMAND='LAST_CMD=$(HISTTIMEFORMAT= history 1 | sed "s/^ *[0-9]\+ *//"); \
printf "%s host=%q ip=%q user=%q cmd=%q\n" "$(date --iso-8601=seconds)" "$LOG_HOST" "$LOG_IP" "$USER" "$LAST_CMD" >> "$CMD_LOG_FILE"; \
history -a'
fi
# Outputs logger
if [ -z "$BASH_OUTPUT_LOGGER_SET" ]; then
export BASH_OUTPUT_LOGGER_SET=1
OUT_LOG_FILE="/var/log/outputs.log"
LOG_HOST="$(hostname)"
LOG_IP="$(hostname -I 2>/dev/null | awk '{print $1}')"
LOG_USER="$USER"
# List of commands to ignore (complex interactive programs)
IGNORE_CMDS=("vim" "nano" "less" "more" "man" "top" "htop" "ssh" "tail" "screen" "tmux")
# Wrap the default command handler
function preexec_invoke_exec() {
if [ -n "$BASH_COMMAND" ]; then
# Extract the first word (command) from the full line
cmd_name=$(echo "$BASH_COMMAND" | awk '{print $1}')
# Check if the command is in the ignore list
for ignore in "${IGNORE_CMDS[@]}"; do
if [ "$cmd_name" == "$ignore" ]; then
# Let the command run normally, don't log output
return 0
fi
done
# Otherwise, log the command and its output
ts="$(date --iso-8601=seconds)"
echo "$ts host=$LOG_HOST ip=$LOG_IP user=$LOG_USER output=" >> "$OUT_LOG_FILE"
eval "$BASH_COMMAND" | tee -a "$OUT_LOG_FILE"
echo "---" >> "$OUT_LOG_FILE"
# Prevent the command from executing a second time
return 1
fi
}
# Use DEBUG trap to intercept commands before they run
trap 'preexec_invoke_exec' DEBUG
fi
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment