I found myself doing something like this alot:
$ some-program-that-changes-file-foo foo > foo.tmp
$ mv foo.tmp foo
Frankly that's kind of annoying. I wrote a little utility called dcat
which allows you to do this:
$ some-program-that-changes-file-foo foo | dcat foo
Since tee has similar behavior (well, more similar than straight cat), I
implemented this behavior when using the -d flag.
I've attached the patch. I hope that you find it useful!
--
Peter D. Kovacs <[EMAIL PROTECTED]>
--- tee.c.orig Wed Mar 13 16:20:50 2002
+++ tee.c Wed Mar 13 16:21:19 2002
@@ -15,7 +15,7 @@
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* Mike Parker, Richard M. Stallman, and David MacKenzie */
+/* Mike Parker, Richard M. Stallman, David MacKenzie, and Peter Kovacs */
#include <config.h>
#include <stdio.h>
@@ -30,7 +30,7 @@
/* The official name of this program (e.g., no `g' prefix). */
#define PROGRAM_NAME "tee"
-#define AUTHORS "Mike Parker, Richard M. Stallman, and David MacKenzie"
+#define AUTHORS "Mike Parker, Richard M. Stallman, David MacKenzie and Peter Kovacs"
int full_write ();
@@ -42,6 +42,9 @@
/* If nonzero, ignore interrupts. */
static int ignore_interrupts;
+/* if nonzero, delay the output */
+static int delay;
+
/* The name that this program was run with. */
char *program_name;
@@ -49,6 +52,7 @@
{
{"append", no_argument, NULL, 'a'},
{"ignore-interrupts", no_argument, NULL, 'i'},
+ {"delay", no_argument, NULL, 'd'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
@@ -68,6 +72,7 @@
\n\
-a, --append append to the given FILEs, do not overwrite\n\
-i, --ignore-interrupts ignore interrupt signals\n\
+ -d, --delay delay writing to output file\n\
--help display this help and exit\n\
--version output version information and exit\n\
"));
@@ -91,8 +96,9 @@
append = 0;
ignore_interrupts = 0;
+ delay = 0;
- while ((optc = getopt_long (argc, argv, "ai", long_options, NULL)) != -1)
+ while ((optc = getopt_long (argc, argv, "aid", long_options, NULL)) != -1)
{
switch (optc)
{
@@ -107,6 +113,10 @@
ignore_interrupts = 1;
break;
+ case 'd':
+ delay = 1;
+ break;
+
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
@@ -167,14 +177,24 @@
int bytes_read, i;
int ret = 0;
const char *mode_string = (append ? "a" : "w");
+ char **delay_files;
descriptors = (FILE **) xmalloc ((nfiles + 1) * sizeof (descriptors[0]));
+ if ( delay )
+ {
+ delay_files = (char**)xmalloc( (nfiles + 1) * sizeof(delay_files[0]) );
+ for (i = nfiles; i >= 1; --i) {
+ delay_files[i] = (char*)xmalloc( (strlen( files[i-1] ) + 6) *
+sizeof(delay_files[0][0]) );
+ sprintf(delay_files[i], "%sXXXXXX", files[i-1] );
+ }
+ }
/* Move all the names `up' one in the argv array to make room for
the entry for standard output. This writes into argv[argc]. */
for (i = nfiles; i >= 1; i--)
files[i] = files[i - 1];
+
SET_BINARY2 (0, 1);
/* In the array of NFILES + 1 descriptors, make
@@ -185,6 +205,17 @@
for (i = 1; i <= nfiles; i++)
{
+ if ( delay ) {
+ int fd = mkstemp( delay_files[i] );
+ if ( fd < 0 || (descriptors[i] = fdopen( fd, mode_string ))
+== NULL) {
+ error (0, errno, "%s", files[i]);
+ ret = 1;
+ } else {
+ SETVBUF (descriptors[i], NULL, _IONBF, 0);
+ SET_BINARY (fileno (descriptors[i]));
+ }
+ } else {
+
descriptors[i] = fopen (files[i], mode_string);
if (descriptors[i] == NULL)
{
@@ -197,6 +228,7 @@
SET_BINARY (fileno (descriptors[i]));
}
}
+ }
while (1)
{
@@ -224,15 +256,25 @@
}
/* Close the files, but not standard output. */
- for (i = 1; i <= nfiles; i++)
+ for (i = 1; i <= nfiles; i++) {
if (descriptors[i] != NULL
&& (ferror (descriptors[i]) || fclose (descriptors[i]) == EOF))
{
error (0, errno, "%s", files[i]);
ret = 1;
}
+ if ( delay ) {
+ if ( rename( delay_files[i], files[i] ) ) {
+ error(0, errno, "%s", files[i] );
+ ret = 1;
+ }
+ free( delay_files[i] );
+ }
+ }
free (descriptors);
+ if ( delay )
+ free( delay_files );
return ret;
}