4

I've often wanted to log the output of Terminal. So I tried to set script to run at startup; in my .bashrc file I put:

script ~/Logs/$(date "+%Y-%m-%d.%H-%M-%S")

Because the commands in my .bashrc file are run whenever I open an interactive terminal, I thought this would do what I wanted.

However, because script itself opens a new terminal during the course of its execution, I instead ended up with a fork bomb:

Last login: Sat May  9 12:02:43 on ttys001
Script started, output file is /Users/mchenja/Logs/2015-05-09.12-14-37
Script started, output file is /Users/mchenja/Logs/2015-05-09.12-14-37
Script started, output file is /Users/mchenja/Logs/2015-05-09.12-14-37
Script started, output file is /Users/mchenja/Logs/2015-05-09.12-14-37
Script started, output file is /Users/mchenja/Logs/2015-05-09.12-14-37
Script started, output file is /Users/mchenja/Logs/2015-05-09.12-14-37
[mchenja@mycomp ~]$

Any tips on how to ensure that script is run exactly once when I open a new interactive terminal?

If it matters, this is on OS X, although I believe the same thing would happen in Linux.

3 Answers 3

1

I reflected on @Thomas Dickey's answer via the "guard variable" and your situation. There are some tricky things going on here and it depends on your environment.

If you're logged into a workstation running X windows, when you log in, the .bash_profile file is read (typically, though I Cannot say for sure about all editions of Linux; it also depends on your login shell). That would start your script session, so that's a bad thing. Further, when you log into a terminal from within X, it will not read .bash_profile, but only .bashrc, unless you tell the terminal software to tell bash that it is a login shell, in which case just the opposite happens.

So here are a few tips:

  • Use $SHLVL to determine if you are at a "top level" invocation of bash, or possibly within an X login session, or possibly within a term/command-prompt within X (or maybe the console!). You can use the tty command to distinguish between console login and terminal login (tty |grep -q ^/dev/tty && echo "is console")
  • .bash_profile will only be read once per login session ... normally. You can also force its reading by invoking bash with -l.
  • If it's a login shell, .bashrc will not be auotmatically read. You run it by sourcing it from within .bash_profile.
  • I believe you want to make sure script is not re-entrant. That is, if you're in a shell with script running, and you create a sub-shell, you don't want script to run again.
  • What happens if you run screen within script?
  • screen has a logging feature which might be more suitable than script. Then you have other problems such as, what happens when you have multiple terminal windows open? Do they each have a separate screen session?
1
  • 1
    I'm an idiot... as you suggested, putting it in .bash_profile instead of .bashrc did the trick. Thanks!
    – user291415
    May 9, 2015 at 20:52
2

You would have to set your own special variable to be tested in .bash_profile, e.g.,

if [ -z "$IN_MY_SCRIPT" ]
then
    export IN_MY_SCRIPT=$(date)
    script ~/Logs/$(date "+%Y-%m-%d.%H-%M-%S")
fi
0

I'm answering the "prevent fork bomb" question in the title, not the one you actually asked. ;)

Put Hard nproc limits in /etc/security/limits.conf as enforced by PAM.

Just a suggestion:

 *        soft   nproc   500
 %users   soft   nofile  256

But this might just screw with something like Apache or MySQL.

You must log in to answer this question.