From: peter@Starbase.NeoSoft.COM (Peter da Silva) Newsgroups: alt.sources Subject: detach -- nohup on steroids Date: 11 Oct 1994 13:20:37 -0500 Organization: NeoSoft Internet Services +1 713 684 5969 After several requests, here's my detach job program. It works pretty much anywhere that has a concept of process groups. # This is a shell archive. Save it in a file, remove anything before # this line, and then unpack it by entering "sh file". Note, it may # create directories; files and directories will be owned by you and # have default permissions. # # This archive contains: # # Makefile # detach.1 # detach.c # echo x - Makefile sed 's/^X//' >Makefile << 'END-of-Makefile' X# standard defines XSHELL=/bin/sh XCFLAGS=-O XSHARFILES=Makefile $(MISC) $(CFILES) XSHAR=$(TARGET).shar X X# program dependent defines XOFILES=detach.o XCFILES=detach.c XTARGET=detach XMISC=detach.1 X Xdefault: $(TARGET) X Xall: $(TARGET) shar X Xshar: $(SHAR) X X$(TARGET): $(OFILES) X $(CC) $(CFLAGS) $(OFILES) -o $(TARGET) X X$(SHAR): $(SHARFILES) X shar >$(SHAR) $(SHARFILES) END-of-Makefile echo x - detach.1 sed 's/^X//' >detach.1 << 'END-of-detach.1' X.TH DETACH 1 X.SH NAME Xdetach -- when it absolutely has to run! X.SH USAGE X.B detach X[ X.B -av X] X[ X.B -f X.I filename X] X.I command X.I args-and-options X.SH DESCRIPTION XThere are rude programs out there that *insist* on knowing when you've Xhit interrupt or logged out. They don't care that you've backgrounded Xthem and nohupped them... as soon as that signal comes in, they're Xgone. X.PP XAlso, sometimes you have a background process run amok. You don't have Xtime to look it up, because it's printing junk all over your screen. XYou have to 'kill -9 0'... but there's another background job there that you don't want to kill. X.PP XWell, there is a solution... Xa little program called 'detach'. Detach is really dumb, Xbut it does its job. What it does is run a command in a whole new Xprocess group. Once you have detached a process, you can airmail Xyour terminal to Brazil. It won't care. It'll just print its process group ID X(suitable for feeding into kill) like the last flash of light as it vanishes Xinto a black hole. X.PP XSo, when you're going to background that 80 hour build, detach it. X.SH OPTIONS X.IP -a XAppend to the log file rather than overwriting it. X.IP -v XPrint the command being executed as well as the PID. X.IP "-f \fBfilename\fR" XUse the named file for the detached job's output other than "detach.out". X.SH NOTES XIt uses setpgrp(0) to create a new process group. I have not found any Xsystem for which this doesn't work, but there's always a first time. END-of-detach.1 echo x - detach.c sed 's/^X//' >detach.c << 'END-of-detach.c' X#include X#include X Xmain(ac, av) Xint ac; Xchar **av; X{ X int pid; X char *file; X int vflag; X int mode; X X close(0); open("/dev/null", 0); X close(1); X X file = "detach.out"; X mode = O_TRUNC; X vflag = 0; X X while(**++av == '-') { X while(*++*av) { X switch(**av) { X case 'f': X if(*++*av) X file = *av; X else X file = *++av; X goto next_arg; X case 'v': X vflag++; X break; X case 'a': X mode = O_APPEND; X break; X } X } Xnext_arg: ; X } X X if(open(file, O_WRONLY|mode|O_CREAT, 0666) < 0) { X perror(file); X exit(1); X } X X switch(pid = fork()) { X case -1: X perror(av[0]); X exit(1); X break; X case 0: X if(vflag) { X char **p = av; X X printf("# %d", getpid()); X while(*p) X printf(" %s", *p++); X putchar('\n'); X } X fflush(stdout); X close(2); dup(1); X setpgrp(); X execv(av[0], av); X execvp(av[0], av); X perror(av[0]); X exit(1); X break; X default: X if(vflag) { X fprintf(stderr, "# %d", pid); X while(*av) X fprintf(stderr, " %s", *av++); X fputc('\n', stderr); X } else X fprintf(stderr, "%d\n", pid); X break; X } X} END-of-detach.c exit -- You summoned forth an Ancient Evil and you don't know what to do with it?