gettmpfile - create temporary files
From time to time I wish I could have temporary files in awk: files with unique names that are removed when my script terminates. Of course I could do a
system("/bin/rm " mytmpfiles);
at the end of the script but the problem here is that it must be guaranted that the system() command is run and the files are removed. One possible way is to put the call into an END section:
END {
system("/bin/rm " mytmpfiles);
}
could to this. For some reason (and now that I think in more detail about it I'm really not sure why) I don't like this way.
Instead I had the idead of making a shell script that is called from awk and that
- creates the files (or better: returns unique filenames), and
- removes the files when the awk script terminates.
The script (find it in the download directory) is
1 #!/bin/sh
2 #
3
4 #
5 # gettmpfile -- get one or more temporary files
6 #
7
8
9 cleanup() {
10 if [ "$TMPFILES" != "" ]; then
11 for i in $TMPFILES; do
12 if [ -f $i ]; then
13 LIST="$LIST $i"
14 fi
15 done
16
17 if [ "$LIST" != "" ]; then
18 rm $LIST
19 fi
20 fi
21 }
22
23 __gettmp() {
24 let 'count = count + 1'
25 tmpfile=$TMPDIR/$prefix-$now-$count
26 TMPFILES="$TMPFILES $tmpfile"
27 }
28
29
30 program=`basename $0`
31 trapsignals="0 1 2 3 15"
32
33 TMPDIR=/tmp
34 prefix=tmp
35 ext=
36
37 options=`getopt de:p:T: $*` || exit 1
38 set -- $options
39 while true; do
40 opt=$1
41 case $opt in
42 -d)
43 set -x
44 shift
45 ;;
46
47 -e)
48 ext=$2
49 shift 2
50 ;;
51
52 -p)
53 prefix=$2
54 shift 2
55 ;;
56
57 -T)
58 TMPDIR=$2
59 shift 2
60 ;;
61
62 --)
63 shift
64 break
65 ;;
66
67 -*)
68 echo $program: unknown option: $opt 1>&2
69 exit 1
70 ;;
71
72 *)
73 break
74 ;;
75
76 esac
77 done
78
79
80
81 #
82 # Check parameters ...
83 #
84
85 if [ "$#" '!=' 0 ]; then
86 echo usage: $program '[<options>]' 1>&2
87 exit 1
88 fi
89
90
91 #
92 # ... capture signals, set some default values ...
93 #
94
95 trap 'cleanup; exit' $trapsignals
96 now=`date +'%s'`
97 pid=`printf '%05d' $PPID`
98 count=0
99
100 #
101 # ... and start.
102 #
103 __gettmp
104 echo $tmpfile
105
106
107 #
108 # Create more temporary filenames as required.
109 #
110
111 while read line; do
112 __gettmp
113 echo $tmpfile
114 done
115
116 exit 0
It's called from awk as a co-process:
cmd = "gettmpfile"; cmd | getline mytempfile;
read the file for the temporary file into the variable mytempfile. After constructing and emitting an initial filename (line #103) the shell script waits for more input (line #111). For every line it gets it returns another name for a temporary file. So in case you have gawk co-processes you can do
cmd = "gettmpfile";
cmd |& getline mytempfile;
printf ("\n") |& cmd;
cmd |& getline myothertempfile;
When the shell script sees that its standard input is closed it terminates; the cleanup() exit handler (line #9) function (set in line #95) removes all temporary files that really exist.
One difference between the shell script and doing it directly in awk might by (I didn't check it) that the shell script removes the temporary files even when it is terminated with one if the usual signal by kill(1); the script catches HUP, INT, QUIT and TERM (see lines #31 and #95).