2

I'm attempting to add to my ~/.zshrc file a command to record the command line inputs and outputs. I have the script (https://www.tecmint.com/record-and-replay-linux-terminal-session-commands-using-script/) command required running but I'm having an issue with it seeming to infinitely attempt to record my session. I believe this is due to the fact that when you run the script command it starts a new bash session which in turn runs the ~/.zshrc which then tries to record the session which restarts the session (etc. etc.). This causes it to get into an infinite loop of attempting to record the session.

Attempt 1 Relevant piece of my ~/.zshrc

# RECORD COMMAND INPUT AND OUTPUT
LOG_PATH=/var/log/terminal/$(date +'%Y%m%d')
LOG_FILE=${LOG_PATH}/$(date +'%H%M%S').log
mkdir -p ${LOG_PATH}
script ${LOG_FILE}

This results in a session which constantly prints the following:

Script started, output file is /var/log/terminal/20200109/141849.log
Script started, output file is /var/log/terminal/20200109/141850.log
Script started, output file is /var/log/terminal/20200109/141851.log
Script started, output file is /var/log/terminal/20200109/141852.log
Script started, output file is /var/log/terminal/20200109/141853.log
Script started, output file is /var/log/terminal/20200109/141854.log
Script started, output file is /var/log/terminal/20200109/141855.log
... repeat infinitely ...

Attempt 2 One attempt at working around this was to check if a file already exists and then go on with recording (which works somewhat but sometimes it creates 2 files or sometimes the recording doesn't start say if I open 2 command sessions in rapid succession).

Upgraded script

# RECORD COMMAND INPUT AND OUTPUT
# Check if the recording of a file for the given time has already started
# as it seems that once you start the script recording it re-starts the session
# which in turn re-runs this file which attempts to script again running into an infinite loop

LOG_PATH=/var/log/terminal/$(date +'%Y%m%d')
LOG_FILE=${LOG_PATH}/$(date +'%H%M%S').log
if [[ ! -f $LOG_FILE ]]; then
        mkdir -p ${LOG_PATH}
        script ${LOG_FILE}
fi

Again this either yields no recording (in the case of opening 2 sessions quickly) or it results in the recording being done twice

Script started, output file is /var/log/terminal/20200109/141903.log
Script started, output file is /var/log/terminal/20200109/141904.log

Attempt 3 Another attempt was to check the bash history and see if the last command contained the word script. Problem with this attempt was that the bash session doesn't seem to have history when starting and hence gave the following error (and then infinitely tried to start the recording session like the first attempt):

# RECORD COMMAND INPUT AND OUTPUT
# Check what the last command was to make sure that it wasn't the script starting
# as it seems that once you start the script recording it re-starts the session
# which in turn re-runs this file which attempts to script again running into an infinite loop

LAST_HISTORY=$(history -1)
if [[ "$LAST_HISTORY" != *"script"* ]]; then
        LOG_PATH=/var/log/terminal/$(date +'%Y%m%d')
        LOG_FILE=${LOG_PATH}/$(date +'%H%M%S').log
        mkdir -p ${LOG_PATH}
        script ${LOG_FILE}
fi

Output

Last login: Thu Jan  9 14:27:30 on ttys009
Script started, output file is /var/log/terminal/20200109/142754.log
Script started, output file is /var/log/terminal/20200109/142755.log
omz_history:fc:13: no such event: 0
omz_history:fc:13: no events in that range
Script started, output file is /var/log/terminal/20200109/142755.log
omz_history:fc:13: no such event: 0
omz_history:fc:13: no events in that range
Script started, output file is /var/log/terminal/20200109/142755.log
Script started, output file is /var/log/terminal/20200109/142756.log
^C%                                                                                                                                                                    danielcarmo@Daniels-MacBook-Pro-2 git %

Any suggestions or thoughts on this would be much appreciated.

DMCApps
  • 2,110
  • 4
  • 20
  • 36
  • _it starts a new bash session which in turn runs the ~/.zshrc_ : Why would a bash session source .zshrc???? – user1934428 Jan 10 '20 at 07:47
  • @user1934428 I'm using iTerm2 with zsh. Guess I should have noted that. – DMCApps Jan 13 '20 at 16:32
  • This makes sense. But then I don't understand, where `bash` comes into play, unless you have in your `.zshrc` a command `bash` or `exec bash` or something similar. – user1934428 Jan 14 '20 at 06:50

2 Answers2

1

Instead of trying to figure out whether or not script is running, simply leave a breadcrumb for yourself:

if [ -z "$BEING_LOGGED" ]
then
  export BEING_LOGGED="yes"
  LOG_PATH="/var/log/terminal/$(date +'%Y%m%d')"
  LOG_FILE="${LOG_PATH}/$(date +'%H%M%S').log"
  mkdir -p "${LOG_PATH}"
  exec script "${LOG_FILE}"
fi

The first time the file is sourced, BEING_LOGGED will be unset. When script is invoked and the file is sourced again, it'll be set, and you can skip logging.

that other guy
  • 116,971
  • 11
  • 170
  • 194
1

script adds the variable SCRIPT to the environment of the command it runs. You can check for that to decide whether script needs to run.

# RECORD COMMAND INPUT AND OUTPUT
log_path=/var/log/terminal/$(date +'%Y%m%d')
log_file=${log_path}/$(date +'%H%M%S').log
mkdir -p "${log_path}"
[ -z "$SCRIPT" ] && script "${log_file}"

The value of SCRIPT is the name of the file being logged to.

chepner
  • 497,756
  • 71
  • 530
  • 681
  • This one is along the same lines as thatotherguy's that I accepted since it was first. This one is cleaner since it uses the build in variable set by the `script` command – DMCApps Jan 13 '20 at 16:32
  • I would have accepted this one instead, so that future readers skimming it will see the cleanest answer highlighted ^^ – that other guy Jan 13 '20 at 17:16
  • Does this still work? I find the `SCRIPT` commandline variable to be empty. – ma08 Aug 07 '22 at 07:59
  • This only applies to some versions of `script`, namely not the one in util-linux. E.g. the [FreeBSD man page](https://www.freebsd.org/cgi/man.cgi?sektion=1&query=script) mentions it, but it's nowhere to be seen with the [man page on Debian](https://manpages.debian.org/bullseye/bsdutils/script.1.en.html). – ilkkachu Aug 08 '22 at 17:21