9

I'm using the script command to save all the output from the terminal to a file called typescript. Or script foo to save to the file foo.

Now, let's say I'm going along typing command after command and I forget whether or not I'm in a typescript or not.

How can I find out if I'm within a typescript or not?

6

Maybe with:

if lsof -tac script "$(tty)" > /dev/null; then
  echo "I'm running under script"
else
  echo "I'm not"
fi

You could add something like:

lsof -tac script "$(tty)" > /dev/null && PS1="[script] $PS1"

To your ~/.zshrc or ~/.bashrc, so the information on whether you're in script or not would be visible on your shell prompt.

Alternatively, if you can't guarantee that lsof be installed you could do (assuming an unmodified IFS):

terminal=$(ps -o comm= -p $(ps -o ppid= -p $(ps -o sid= -p "$$")))
[ "$terminal" = script ] && PS1="[script] $PS1"

The heuristic is to get the command name of the parent of the session leader which generally would be the terminal emulator (xterm, script, screen...).

  • 1
    @teikakazura, the heuristic part was because you're not guaranteed that it will be the parent process of the session leader. Nothing to do with pid reuse here as your session leader and its parent will typically still be around when you run that command. You could say that the first one is heuristic as well as we're just checking the process name. Any command whose name is also script and has the tty open would also cause a false positive. – Stéphane Chazelas Feb 23 '17 at 7:28
  • 1
    @teikakazura About (2), that would check the ppid of the current shell. Here, you want to check the ppid of the session leader (typically, that would be the shell that script started). – Stéphane Chazelas Feb 23 '17 at 7:28
5

Interesting problem. I found a small bash script could do the job pretty reliably:

#!/bin/bash

PP=$(ps -o ppid= $$)

while [[ $PP != 1 ]]
do
    LINE=$(ps -o ppid= -o comm= $PP | sed 's/^  *//')
    COMM=${LINE#* }
    PP=${LINE%% *}
    if [[ $COMM == script ]]  # Might need a different comparison
    then
        echo "In script"
        exit 0
    fi
done
echo "Not in script"

I think this is slightly different than proposed by Stephane Chazelas, in that my script works its way up the parent:child relationship that Linux/Unix processes have until it finds PID 1, or it finds "script" as the process.

  • 3
    Interesting approach. However, note that if for instance, you start an xterm from your script session, that script will thing the shell in that xterm is running under script. Well it is in a way, but the output is not going to the typescript. My approach checks the terminal associated with the current session so would not have that issue. – Stéphane Chazelas Mar 20 '13 at 18:34
0

If you have a personal bin/ directory in your path (e.g. /home/user/bin, place a shell script there with the name 'script' (same name as the binary), with the following contents:

#!/bin/bash
export SCRIPT_RUNNING=1
exec /usr/bin/script # full path to your script(1) binary

Now, within script running, you can test for the environment variable SCRIPT_RUNNING, and do whatever you want based on it.

EDIT:

Actually, there's a far easier way. The following says it all, create three files, ~/bin/script, ~/bin/script-shell and ~/.scriptrc:

~ > ls ~/bin/script ~/bin/script-shell ~/.scriptrc
-rw-r--r-- 1 roadowl users 23 Oct 18 16:52 /home/roadowl/.scriptrc
-rwx------ 1 roadowl users 49 Oct 18 16:53 /home/roadowl/bin/script
-rwx------ 1 roadowl users 56 Oct 18 16:55 /home/roadowl/bin/script-shell

~/bin > cat script
#!/bin/bash
exec /usr/bin/script -c script-shell

~/bin > cat script-shell
#!/bin/bash
exec /bin/bash --rcfile /home/bjd/.scriptrc

~/bin > cat ~/.scriptrc
export PS1="[script] "

If your current shell is bash, don't forget to run hash -r after creating these files, to ensure ~/bin/script is run when 'script' is entered as a command (check with which script).

As before, note that you must have ~/bin in your PATH, preceding the standard path for this to work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.