Error output of cat to /dev/null

Hello,

I'm trying to send the error output of a 'cat' operation to /dev/null like this:

cat /dirA/dirB/temp*.log  > /dirA/dirB/final.log 2>/dev/null

This works perfectly in a terminal, but not when placed in a script.

If there are no files matching temp*.log the script outputs an error saying: /dirA/dirB/final.log: No such file or directory.

The same problem occurs on the next line in the script where I want to remove all temp*.log files

rm /dirA/dirB/temp*.log 2>/dev/null

Sending all errors of the script to /dev/null is not an option as I need error information from other parts of the script.

Anybody an idea as to how to solve this

What Operating System and version?
What Shell?
How many files?
Was the script created on the unix server with a proper unix editor such as "vi" ? If not, what was used.

uname -a
echo $SHELL
find /dirA/dirB/ -name temp\*.log -print | wc -l
sed -n l scriptname

I'm writing/testing the script on

  • Linux pclinux 2.6.15-27-386 #1 PREEMPT Sat Sep 16 01:51:59 UTC 2006 i686 GNU/Linux (ubuntu dapper drake)

  • /bin/bash
    But eventually it needs to run on

  • Linux embLinux 2.6.12 #184 Wed Dec 9 08:35:30 CET 2009 armv4tl unknown

  • /bin/sh
    The results are the same on both systems

  • anything between 0 and 100 files

  • the files are created using gedit

`cat /dirA/dirB/temp*.log > /dirA/dirB/final.log 2>/dev/null`$
`rm /dirA/dirB/temp*.log 2>/dev/null`$

Just for interest the $ sign (only) at the end of the line when viewed with "sed" tells me that this is a normal unix text file.

The problem with the script is the backticks. Not required in this context and will cause the error you are seeing. It will try to execute each file in the directory list and fail on the first one because it is not in $PATH !

Try this:

cat /dirA/dirB/temp*.log > /dirA/dirB/final.log 2>/dev/null
rm /dirA/dirB/temp*.log 2>/dev/null

Removving the backticks is no solution, the result is the same (I had already played with this).

It is not first file on which it gives an error, it gives an error that the final file does not exist. It looks as though the system has difficulties with writing "nothing" to a file that does not exist.

you could try and send the error of the cat to null

cat /dirA/dirB/temp*.log 2>/dev/null > /dirA/dirB/final.log 2>/dev/null

or you could trap all standard error out to null

MY_ERR="/dev/null"
exec 2>$MY_ERR

cat /dirA/dirB/temp*.log > /dirA/dirB/final.log
rm /dirA/dirB/temp*.log

I stand corrected. You get the issue I mentioned with `ls` (don't try it!).

Any space characters or non-printing characters in the filenames?
Is the directory automounted from another computer?

We can check that the filename globbing is working and check that the Shell generates the complete line.

echo cat /dirA/dirB/temp*.log

Btw. I hate open-ended lists on command lines. This construct more robust:

>/dirA/dirB/final.log
ls -1 /dirA/dirB/temp*.log 2>/dev/null | while read filename
do
         cat "${filename}" >>/dirA/dirB/final.log ; REPLY=$?
         if [ ${REPLY} -eq 0 ]
         then
               rm "${filename}"
         fi
done
cat /dirA/dirB/temp*.log  > /dirA/dirB/final.log 2>/dev/null && rm /dirA/dirB/temp*.log

Perhaps it is safer to use:

cat /dirA/dirB/temp*.log  >> /dirA/dirB/final.log 2>/dev/null && rm /dirA/dirB/temp*.log

Otherwise final.log will be overwritten if there are no files...

The second 2>/dev/null serves no purpose. The order is not important in this case. For example this would work also:

> /dirA/dirB/final.log 2>/dev/null cat /dirA/dirB/temp*.log && rm /dirA/dirB/temp*.log