[comp.unix.shell] emptying a file and keeping its ownership

ckchee@dgp.toronto.edu (Chuan Chee) (12/31/90)

I have SCO Xenix 2.2.3.  What's the easiest way to "empty" a file
while keeping its ownership (owner,group) and access permissions the
same?  Actually I only care about permissions (rw-rw-rw).
I would like this done in Bourne shell (or possibly CSH).
One other thing, this shell script is run under root.

Here's the way I currently do it:
  rm -f $FILE
  touch $FILE
  chmod +w $FILE
  chown $OWNER $FILE
  chgrp $GRP $FILE

Thanks in advance.

...Chuan Chee
   ckchee@dgp.utoronto.ca
   ckchee@dgp.toronto.edu (internet)
   ckchee@dgp.utoronto    (bitnet)

karish@mindcraft.com (Chuck Karish) (12/31/90)

In article <1990Dec30.220722.29050@jarvis.csri.toronto.edu>
ckchee@dgp.toronto.edu (Chuan Chee) writes:
|I have SCO Xenix 2.2.3.  What's the easiest way to "empty" a file
|while keeping its ownership (owner,group) and access permissions the
|same?  Actually I only care about permissions (rw-rw-rw).

  > $FILE

A redirect with no input truncates the file under Bourne shell.
-- 

	Chuck Karish		karish@mindcraft.com
	Mindcraft, Inc.		(415) 323-9000		

donlash@uncle.uucp (Donald Lashomb) (12/31/90)

In article <1990Dec30.220722.29050@jarvis.csri.toronto.edu> ckchee@dgp.toronto.edu (Chuan Chee) writes:
=I have SCO Xenix 2.2.3.  What's the easiest way to "empty" a file
=while keeping its ownership (owner,group) and access permissions the
=same?  Actually I only care about permissions (rw-rw-rw).
=I would like this done in Bourne shell (or possibly CSH).
=One other thing, this shell script is run under root.

This works for me:
	> file      # shell opens file for writing, and writes 0 bytes

hope this is what you are looking for
-Don

msb@hosmsb.ATT.COM (Mike Balenger) (01/01/91)

>>>>> On 31 Dec 90 03:07:23 GMT, ckchee@dgp.toronto.edu (Chuan Chee) said:

ckchee> I have SCO Xenix 2.2.3.  What's the easiest way to "empty" a
ckchee> file while keeping its ownership (owner,group) and access
ckchee> permissions the same?  Actually I only care about permissions
ckchee> (rw-rw-rw).  I would like this done in Bourne shell (or
ckchee> possibly CSH).  One other thing, this shell script is run
ckchee> under root.

ckchee> Here's the way I currently do it:
ckchee>   rm -f $FILE
ckchee>   touch $FILE
ckchee>   chmod +w $FILE
ckchee>   chown $OWNER $FILE
ckchee>   chgrp $GRP $FILE

This works in ksh and sh on SysV.  I guess it should work for other
UNIX look-alike's and shell look-alike's.

    > $FILE

Since you don't remove the file, you don't need to recreate it.  The
file is truncated as a consequence of the defined behavior of output
redirection, but since there is no command, no output is generated
into the file.  An added bonus, this method preserves links.  They are
lost with the "rm" in your original solution.

You must, of course, have write permission to the file to try this.
If that doesn't suite your fancy, try this
    > $FILE && { some machinations on ">", "mv", "cp" & "chmod" }

The assorted machinations will only happen if the redirection fails --
most likely due to lack of write permission.  This probably isn't a
problem if you run a root, but may be useful for less-than-root uses.

Note that the modification time is not changed if the file was already
zero length.  If you need that behavior, add
    touch $FILE



--
----------------------------------------------------------------------
<cute quote>            Michael S. Balenger             (908) 949-8789
<cute disclaimer>       AT&T Bell Labs	           FAX: (908) 949-7512
M_Balenger@att.com      Room 1L-405
msb@hos1cad.att.com     Crawfords Corner Road
att!hos1cad!msb         Holmdel, NJ   07733-1988

segrove@PacBell.COM (S. E. Grove) (01/01/91)

Summary: > $FILE will do the job. 



        Stephen Grove  Comm. Tech. ESS Pacific Bell
	segrove@pbhya.PacBell.COM
	PacBell.COM!{rtpkh0,rtpkh1}!segrove
-- 
        Stephen Grove  Comm. Tech. ESS Pacific Bell
	seg@pbhya.PacBell.COM
	segrove@pbhya.PacBell.COM (After 12-14-90)
	PacBell.COM!{rtpkh0,rtpkh1}!segrove

dberg@informix.com (David I. Berg) (01/01/91)

> I have SCO Xenix 2.2.3.  What's the easiest way to "empty" a file
> while keeping its ownership (owner,group) and access permissions the
> same? 

How about:
	cat /dev/null >! $FILE
  ___                   ___              dberg@cougar.informix.com
  /  ) __      . __/    /_ ) _       __  Informix Software Inc.  (303) 850-0210
_/__/ (_(_ (/ / (_(_  _/__> (-' -/~ (_-  5299 DTC Blvd #740; Englewood CO 80111
{uunet|pyramid}!infmx!dberg
The opinions expressed herein do not necessarily reflect those of Informix Inc.

john@cstreet.com (John Poplett) (01/01/91)

In article <1990Dec30.220722.29050@jarvis.csri.toronto.edu> ckchee@dgp.toronto.edu (Chuan Chee) writes:
>I have SCO Xenix 2.2.3.  What's the easiest way to "empty" a file
>while keeping its ownership (owner,group) and access permissions the
>same?  Actually I only care about permissions (rw-rw-rw).
>I would like this done in Bourne shell (or possibly CSH).
>One other thing, this shell script is run under root.
>

The simplest way to truncate a file using the Bourne shell
is:

> file

Here's a short Bourne shell script that truncates files. Cut it
out and save it to trunc.sh and run "make trunc" to get an executable
script file.

John

------ cut here -------- cut here -------- cut here --------
: 
# @(#)trunc.sh -- truncate or create empty files. Optionally, setting 
# owner or group ID.

usage()
{
	echo "usage: $0 [-o owner] [-g group] file1 [file2...]" 1>&2
	exit 1
}

if [ $# -lt 1 ]
then
	usage
fi

set -- `getopt g:o: $*`

if [ $? != 0 ]
then
	usage
fi

for i in	$*
do
	case $i in
	-g)	      group=$2;	shift; shift;;
	-o)	      owner=$2;	shift; shift;;
	--)       shift; break;;
	esac
done

for file in $*
do
	> $file
done

if [ $group ]
then
	chgrp $group $*
fi

if [ $owner ]
then
	chown $owner $*
fi

exit 0
-- 
John Poplett @ C Street Software     | Never make forecasts, especially
312 Wolff St. Oxnard, Ca. 93033 USA  | about the future.
(805) 486-7807 / john@cstreet.com    |  ~ Sam Goldwyn

jik@athena.mit.edu (Jonathan I. Kamens) (01/01/91)

  Several people have suggested using

    > $FILE

to truncate a file while retaining its old permissions.  This will work under
sh or ksh or bash or other shells that allow null commands for redirection. 
Unfortunately, csh and tcsh do not allow such null commands :-(.  Therefore,
I'd like to point out another way to do this that works on most platforms I've
seen.

  From the man page for cp(1):

    DESCRIPTION
         File1 is copied onto file2.  By default, the mode and owner
         of file2 are preserved if it already existed; otherwise the
         mode of the source file modified by the current umask(2) is
         used.

Therefore, you can use

    cp /dev/null $FILE

to truncate a file and save its current permissions.

  I hope this helps.

-- 
Jonathan Kamens			              USnail:
MIT Project Athena				11 Ashford Terrace
jik@Athena.MIT.EDU				Allston, MA  02134
Office: 617-253-8085			      Home: 617-782-0710

allbery@NCoast.ORG (Brandon S. Allbery KB8JRR) (01/01/91)

As quoted from <1990Dec31.214030.7816@athena.mit.edu> by jik@athena.mit.edu (Jonathan I. Kamens):
+---------------
|   Several people have suggested using
|     > $FILE
| to truncate a file while retaining its old permissions.  This will work under
| sh or ksh or bash or other shells that allow null commands for redirection. 
| Unfortunately, csh and tcsh do not allow such null commands :-(.  Therefore,
+---------------

	% ls -s file
	4 file
	% echo > file
	% ls -s file
	0 file
	% _

Not that I like csh's echo behavior in this case, but it does get around the
"null command" problem.

++Brandon
-- 
Me: Brandon S. Allbery			    VHF/UHF: KB8JRR on 220, 2m, 440
Internet: allbery@NCoast.ORG		    Packet: KB8JRR @ WA8BXN
America OnLine: KB8JRR			    AMPR: KB8JRR.AmPR.ORG [44.70.4.88]
uunet!usenet.ins.cwru.edu!ncoast!allbery    Delphi: ALLBERY

speelmo@bronze.ucs.indiana.edu (Lance Speelmon -- UCS) (01/11/91)

I think the easiest way to do this is:
cp /dev/null <FILE>

Lance

In article <1990Dec30.220722.29050@jarvis.csri.toronto.edu> ckchee@dgp.toronto.edu (Chuan Chee) writes:
>I have SCO Xenix 2.2.3.  What's the easiest way to "empty" a file
>while keeping its ownership (owner,group) and access permissions the
>same?  Actually I only care about permissions (rw-rw-rw).
>I would like this done in Bourne shell (or possibly CSH).
>One other thing, this shell script is run under root.
>
>Here's the way I currently do it:
>  rm -f $FILE
>  touch $FILE
>  chmod +w $FILE
>  chown $OWNER $FILE
>  chgrp $GRP $FILE
>
-- 
==============================================================================
| Lance Speelmon                      |  University Computing Services       | 
| speelmo@bronze.ucs.indiana.edu      |  Network Operations Center           |
==============================================================================

]) (01/12/91)

>I think the easiest way to do this is:
>cp /dev/null <FILE>

That costs a fork/exec of cp...

>>I have SCO Xenix 2.2.3.  What's the easiest way to "empty" a file
>>while keeping its ownership (owner,group) and access permissions the
>>same?  Actually I only care about permissions (rw-rw-rw).
>>I would like this done in Bourne shell (or possibly CSH).
>>One other thing, this shell script is run under root.
>>
>>Here's the way I currently do it:
>>  rm -f $FILE
>>  touch $FILE
>>  chmod +w $FILE
>>  chown $OWNER $FILE
>>  chgrp $GRP $FILE

...and that assumes that the FILE needs to be umask permissions
plus write-permission for everyone, and costs five fork/execs.
It also requires whatever processing preceeded the sample code
to determin OWNER and GRP.  Ideally, that processing would have
included a setting of MODE so that the chmod +w $FILE would be
replaced with a chmod $MODE $FILE to maintain the mode.

What I usually do is

        : > $FILE

at least in a SVR3 system, the permissions and ownerships are
maintained.  (I tested this by: echo a > junk; chmod 666 junk;
chown someone_else junk; : > junk -- the ls -l junk results
were unchanged across the : > junk command.  My umask is 022.)
Execution is controlled based on all applicable file permissions,
and you don't go through a possibly long (from a computer's time
sense) period when the file either doesn't exist at all or exists
with root and root's current group and the wrong mode.

Remember, too, that the datablocks for the file won't actually
be freed until all processes using the file at the outset are
finished.  (Which is to say that if a process has it open on
write, the old file will continue to grow until that other
process is complete and the open-count on the file goes to 0;
only *then* will you gain your disk-space back.)  This is true
regardless of the method applied for zeroing the contents out.

...Kris
-- 
Kristopher Stephens, | (408-746-6047) | krs@uts.amdahl.com | KC6DFS
Amdahl Corporation   |                |                    |
     [The opinions expressed above are mine, solely, and do not    ]
     [necessarily reflect the opinions or policies of Amdahl Corp. ]

msb@hosmsb.ATT.COM (Mike Balenger) (01/16/91)

>>>>> On 12 Jan 91 01:20:03 GMT, krs@uts.amdahl.com (Kris Stephens [Hail Eris!]) said:

krs> What I usually do is

krs>         : > $FILE

The ":" doesn't seem to add anything here.  The following is
equivalent.  (Or am I missing something?)

	> $FILE


--
----------------------------------------------------------------------
<cute quote>            Michael S. Balenger             (908) 949-8789
<cute disclaimer>       AT&T Bell Labs	           FAX: (908) 949-7512
M_Balenger@att.com      Room 1L-405
msb@hos1cad.att.com     Crawfords Corner Road
att!hos1cad!msb         Holmdel, NJ   07733-1988