- Community Home
- >
- Servers and Operating Systems
- >
- Operating Systems
- >
- Operating System - Linux
- >
- Re: How do "find .... -exec cat /dev/null > {} \; ...
Categories
Company
Local Language
Forums
Discussions
Forums
- Data Protection and Retention
- Entry Storage Systems
- Legacy
- Midrange and Enterprise Storage
- Storage Networking
- HPE Nimble Storage
Discussions
Discussions
Discussions
Discussions
Forums
Forums
Discussions
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
- BladeSystem Infrastructure and Application Solutions
- Appliance Servers
- Alpha Servers
- BackOffice Products
- Internet Products
- HPE 9000 and HPE e3000 Servers
- Networking
- Netservers
- Secure OS Software for Linux
- Server Management (Insight Manager 7)
- Windows Server 2003
- Operating System - Tru64 Unix
- ProLiant Deployment and Provisioning
- Linux-Based Community / Regional
- Microsoft System Center Integration
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Community
Resources
Forums
Blogs
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО12-18-2007 06:53 AM
тАО12-18-2007 06:53 AM
Hello everyone,
I am looking for a way of reset files (cat /dev/null > MY_FILE) using the "find ... -exec" construction. This doesn't work:
find /tmp -name "my_file.pp.*" -mtime "+15" -exec cat /dev/null > {} \;
neither:
find /tmp -name "my_file.pp.*" -mtime "+15" -exec cat /dev/null \> {} \;
find /tmp -name "my_file.pp.*" -mtime "+15" -exec " cat /dev/null > {} " \;
I also know this other method to do the job (it works OK):
find /tmp -name "my_file.pp.*" -mtime "+15" -print | while read file_to_reset
do
cat /dev/null > $file_to_reset
done
Someone knows how to write a working "-exec" versi├│n (please try before) similar to the first example ?
Thanks,
Victor
Solved! Go to Solution.
- Tags:
- find
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО12-18-2007 06:58 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО12-18-2007 07:26 AM
тАО12-18-2007 07:26 AM
Re: How do "find .... -exec cat /dev/null > {} \; "
OK. You are rigth.
But my question is a particular case of a more general one. Really I am looking for a way of use the shell redirection (">") inside the "-exec" clause of "find".
Any idea?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО12-18-2007 08:35 AM
тАО12-18-2007 08:35 AM
Re: How do "find .... -exec cat /dev/null > {} \; "
In cases like this, create a small shell script that is 'exec'ed. For example:
# find /tmp -type f -name "my_file.pp*" -mtime +15 -exec /tmp/wrapper {} \;
...where:
# cat /tmp/wrapper
#!/usr/bin/sh
cat /dev/null > $@
exit 0
NOTE that I deliberately chose the form of '-exec' that spawns ONE process per invocation. This allows the executed script to be simple insofar as only one file argument is expected. If you use '-exec /tmp/wrapper {} +' instead, multiple file names would be passed and the wrapper would need to look like:
# cat /tmp/wrapper
#!/usr/bin/sh
while [ $# -gt 0 ]
do
cat /dev/null > $1
shift
done
exit 0
Regards!
...JRF...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО12-18-2007 07:37 PM
тАО12-18-2007 07:37 PM
Re: How do "find .... -exec cat /dev/null > {} \; "
It looks like you can't do it. I tried using \> and even using sh -c "> {}". Unfortunately -exec doesn't replace the {} and so the shell creates a file "{}".
So you need to use cp as Robert-Jan suggests. Or do as JRF suggests, write an auxiliary script. Or use your while read loop.
Note: you don't need to use cat(1) in your script. "> $1" works just as well.
- Tags:
- evil cat
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО12-19-2007 12:51 AM
тАО12-19-2007 12:51 AM
Re: How do "find .... -exec cat /dev/null > {} \; "
Think about how the entire command line is parsed:
1.) The shell expands any unescaped variables and performs any unescaped redirections before the find command is executed. The "{}" construct has no special meaning for the shell, so it's left unchanged. Any escaped characters become unescaped.
2.) The find command begins executing, and when finding a file that matches the conditions, it fork()s a new process, replaces the "{}" with the name of the file and exec()s the command.
NOTE: there is no shell involved in starting the command.
3.) To use the shell redirection for each matching file separately, a shell must start up at this point. Furthermore, it must take its command input from the command line. Looks like "sh -c" might be needed here.
So, here's my first idea:
find /tmp -type f -name "my_file.pp*" -mtime +15 -exec sh -c "> {}" \;
Works on Linux... but not on HP-UX. Hmm.
After a bit of experimentation, it seems that HP-UX "find -exec" does not like having its {} enclosed in double quotes. In addition, the sh of HP-UX (on my "toy" 11.00 at least) apparently does not need nor want the -c option for this.
So, let's try an alternative method of quoting:
find /tmp -type f -name "my_file.pp*" -mtime +15 -exec sh \> {} \;
MK
- Tags:
- quoting
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО12-19-2007 01:31 AM
тАО12-19-2007 01:31 AM
Re: How do "find .... -exec cat /dev/null > {} \; "
The rotten man page doesn't go into any detail on mixing -c "string" with arg. Probably because it thinks the first arg must be a script.
>let's try an alternative method of quoting:
... -exec sh \> {} \;
Well this works. But adding any other tokens like cat would make it fail.
I'm not sure I'd depend on this.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО12-19-2007 06:43 AM
тАО12-19-2007 06:43 AM
Re: How do "find .... -exec cat /dev/null > {} \; "
I don't have POSIX standard documents handy, but I did some tests on a Sun Solaris. It seems to behave the same, so I think this might be POSIXLY_CORRECT behaviour. Maybe the "most obvious" implementation of the standard is not the most useful one?
The problem seems to be two-fold:
1.) The "-c" option of sh seems to have some hidden assumptions and the man page of "sh-posix" does not offer any details.
If you do
sh -c 'echo !$0!$1!$2!' foo
the output is
!foo!!!
which seems to indicate the first arg becomes $0, not $1 as one might expect.
2.) The "find ... -exec" requires "{}" as a separate command line parameter. It cannot be embedded in a longer string. With GNU find, this is allowed.
The interaction between these two things makes it hard or impossible to write a reliable one-liner for this kind of job.
MK
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО12-19-2007 07:44 AM
тАО12-19-2007 07:44 AM
Re: How do "find .... -exec cat /dev/null > {} \; "
There is yet another way to trim your files; use Perl:
# perl -MFile::Find -e 'die unless @ARGV;find(sub{truncate($File::Find::name,0) if -f && -M>15 && m/my_file\.pp\..*/},@ARGV)' /tmp
This performs the same selection that you showed in your opening post with the addition that the action is restricted only to *files* in the directory offered.
For safety, I have let the script fail unless a directory (path) is provided as the command-line script's argument.
You will probably find this to be faster than 'exec'ing any wrapper script as I first suggested since everything is done in the one Perl process.
Regards!
...JRF...