There are cases when we want to record the command that we input into the terminal or even the output. In this case, we will use the history command and the script command.
The script Command
Consider a case when we need to record the terminal for submitting it to someone for auditing or later review. We will need to get both the input and the corresponding output of the terminal. In that case, we use the script command.
According to the command manual, the script command is described as: script makes a typescript of everything displayed on your terminal. It is useful for students who need a hard-copy record of an interactive session as proof of an assignment, as the typescript file can be printed out later.
Script Command Common Usage:
Start the script session to a file. If filename is not specified, it uses the default one named typescript in the current path. To exit the session, type exit or press Ctrl + d.
Input $ script typescript Script started, file is typescript $ exit Script done, file is typescript
Output $ cat typescript Script started on Sunday 11 August 2019 08:14:09 AM IST $ exit Script done on Sunday 11 August 2019 08:14:11 AM IST
Start a script session by appending to a file. The existing contents will not be overwritten.
script -a <filename>
Input $ script typescript Script started, file is typescript $ #test123 $ exit Script done, file is typescript $ script -a typescript Script started, file is typescript $ #test456 $ exit Script done, file is typescript
Output $ cat typescript Script started on Sunday 11 August 2019 08:16:47 AM IST $ #test123 $ exit Script done on Sunday 11 August 2019 08:16:56 AM IST Script started on Sunday 11 August 2019 08:17:00 AM IST $ #test456 $ exit Script done on Sunday 11 August 2019 08:17:12 AM IST
While starting a script session, you will see a dialogue that the session has started. Using the -q option, you can hide this. However, this will be there in the typescript file.
script -q <filename>
Input $ script -q typescript $ #test45 $ exit
Output $ cat typescript Script started on Sunday 11 August 2019 08:20:47 AM IST $ #test45 $ exit Script done on Sunday 11 August 2019 08:21:12 AM IST
You can record the typescript of a certain command rather than going to an interactive session.
script -c “<command>” <filename>
Input $ script -c "free -m" typescript Script started, file is typescript total used free shared buff/cache available Mem: 7865 4885 179 835 2799 1764 Swap: 7812 0 7812 Script done, file is typescript
Output $ cat typescript Script started on Sunday 11 August 2019 08:28:07 AM IST total used free shared buff/cache available Mem: 7865 4885 179 835 2799 1764 Swap: 7812 0 7812 Script done on Sunday 11 August 2019 08:28:07 AM IST
There are certain cases where you need to get a real-time recording like running commands like top or htop. Then we use a timing file which stores the data timing. The output cannot be print using cat command instead, use scriptreplay. This will show you a replay similar to a video of the executed commands.
script <filename> --timing=<timing_filename>
scriptreplay -s <filename> -t <timing_filename>
The history Command
The history command helps us get the command input history. However, usually, common terminal history has a size of 500-1000 records. After this, the old ones are rewritten. You can find the current size from a terminal by issuing the below command.
$ echo $HISTSIZE
$ echo $HISTSIZE 500
You can set the size to a higher value if required. Another limitation is that you will only see the record number and command typed in the usual history output. You can tweak it to display the date and time as well using the below command.
$ HISTTIMEFORMAT="%d/%m/%y %T "
Output $ history ... 11 11/08/19 09:36:49 HISTTIMEFORMAT="%d/%m/%y %T " 12 11/08/19 09:36:51 history
We have set an environmental variable, which can be changed when the session is logged out. So, to make it permanent, we export it to the bash startup files.
$ echo 'export HISTTIMEFORMAT="%d/%m/%y %T "' >> ~/.bash_profile
We can regularly keep a log of the input command history by using the PROMPT_COMMAND variable. The variable will be temporary, exporting it to bash startup files make it permanent. This will overcome the limitation of the HISTSIZE.
$ export PROMPT_COMMAND='if [ "$(id -u)" -ne 0 ]; then echo "$(date "+%Y-%m-%d.%H:%M:%S") $(pwd) $(history 1)" >> ~/logs/bash-history-$(date "+%Y-%m-%d").log; fi'
The contents of the variable PROMPT_COMMAND are executed as a regular bash command just before Bash displays a prompt. Here, we first check if the user is root. If not root, then find the date, time, current working directory, and the current history and write to a log file under /home/username/logs/bash-history-date. You can tweak the line and enable it for the root also.
Making Changes Permanent
So far, we have gone through the common history command usage and script command usage. Now we can make those changes permanent in a production environment. For that, we will need to export and add some commands in the shell startup files.
There are two types for interactive bash shells: login and non-login shell.
We get a login shell when we first login to the system and that shell load the GUI we see. We can get to different login shell by using Ctrl + Alt + F1 to F6. F7 will get us back to the GUI. While we SSH into a system, we are on a login shell. A login shell loads the file ~/.bash_profile first. So we add the lines there.
~/.bash_profile #01.To log history daily to file under /home/username/logs/ export PROMPT_COMMAND='if [ "$(id -u)" -ne 0 ]; then echo "$(date "+%Y-%m-%d.%H:%M:%S") $(pwd) $(history 1)" >> ~/logs/bash-history-$(date "+%Y-%m-%d").log; fi' #02.To see date and time on the command prompt export PS1='[\d] [\t] \u@\h:\w\$ ' #03.To start a script session by default when opening a login shell script -a ~/logs/script-file-$(date "+%Y-%m-%d").log
01. Is the history login that we discussed above.
02. Is used to get the date and time on the command prompt so that we get an understanding when a command is entered. A sample output of this is:
[Sun Aug 11] [11:02:43] user@system:~$ echo $PS1 [\d] [\t] \u@\h:\w\$ [Sun Aug 11] [11:02:43] user@system:~$ echo “Hello” Hello +PS1, PS2, …, PSn are the shell variables. \d represents the date, \t represents time in 24 Hrs (\T for 12 Hrs time), \u represents the username, \h represents hostname, \w the current working directory and \$ gives # if the effective UID is 0, otherwise a $.
03. Is to start a script session as soon as a login prompt is opened. This will help in recoding the activities after the login.
You can add the above 01 and 02 commands in a non-login shell at ~/.bash_rc and it will give the same functionality. However, adding the script command (03) in the files gives an infinite script session running. To execute the command in the normal non-login shell, first make the shell login by following below for Linux terminal:
Go to Edit > Profiles.
Select your Default profile and click on Edit.
Go into the “Title and Command” tab.
Select “Run command as login shell” option.
Click on Close button.
To check if a prompt is a login or non-login, type the command echo $0. If “-” is the first character, then it is a login shell, else, non-login.
# echo $0 -bash # echo $0 bash
We have now managed to log the activities on a terminal session.