Shell script file check throws [: too many arguments

While I am trying to check the filename/s in IF statement of a shell script (RedHat Linux 6) I am getting below error:

File check:

filename_time2=`date --date='yesterday' +%Y-%m-%d`
cd /location/of/the/files/to/copy

if [ -f server.log-$filename_time2* ]
then
                cp server.log-$filename_time2* ../archive/new
                echo Successfully copied
else
                echo No server log files present with timestamp $filename_time2
fi
This throws the error -        [: too many argument

Throws error when there are multiple files in the location. But when there is 1 file match in the location it is working fine.

I have already tried with below options :

if [ -f "server.log-$filename_time2*" ]
if [[ -f "server.log-$filename_time2*" ]]
if [[ -f server.log-$filename_time2* ]]

All the above cases it is not throwing error but it returns FALSE and executing the else block although the file is present in the location with timestamp

Could you please help me how I can use the if condition here to check whether the files are present in the location.

Thanks.

Maybe something more like:

filename_time2=$(date --date='yesterday' +%Y-%m-%d)
cd /location/of/the/files/to/copy

for file in server.log-$filename_time2*
do	if [ -f "$file" ]
	then
		cp server.log-$filename_time2* ../archive/new
		exitcode=$?
		echo "One or more files with timestamp $fiename_time2 copied"
		exit $exitcode
	else
		echo "No server log files present with timestamp $filename_time2"
		exit 1
	fi
done
1 Like

Thanks for your suggestion @Don Cragun.

Actually in my case always there are always some server.log file present with timestamp. So I would always like to check the if statement with timestamp.
I tried after your suggestion like the below:

filename_time2=$(date --date='yesterday' +%Y-%m-%d)
file=audit.log-$filename_time2*

                if [ -f "$file" ]
                then

                     cp server.log-$filename_time2* ../archive/new
		     exitcode=$?
		     echo "One or more files with timestamp $fiename_time2 copied"
		     exit $exitcode
	         else
		     echo "No server log files present with timestamp $filename_time2"
		     exit 1
	          fi

This is also failed to find the files so the else block is executing.

DonCragun's code as posted would have worked. You modified a crucial part of that code, vis

for file in server.log-$filename_time2*

This expands the wildcard; the if statement then checks the first file in the list. If that file exists all the files are copied at once and the loop is terminated.
Try the code again as posted in post 2 of this thread rather than modified by you.

Andrew

1 Like

Expanding a bit on what Andrew already said...

Did you try the code I suggested in post #2 in this thread?

If so, in what way did it fail?

Are you saying that you have some files that will match the filename matching pattern audit.log-$filename_time2* that are regular files and there are other filenames matching that pattern at the same time that are of some other filetype?

From what you stated in post #1, I assumed that you either had one or regular files that would match that pattern or that there were no existing files that would match that pattern. If that is the case, the code I suggested should have done exactly what you wanted it to do (assuming that you are using a shell that meets a fairly minimal subset of the requirements for the shell command programming language specified by the POSIX standards).

The code that you are trying (calling test (or it alias [ ) with multiple filename operands or with a quoted filename matching pattern containing wild-card characters cannot ever be convinced to do what you are trying to do if more than one file exists matching that pattern. The test with more than one file operand is always going to give you the diagnostic message you reported seeing in post #1.

If, however, it is always the case that at least one existing filename will match your filename matching pattern, then there is no need for the test command at all and you can just replace your entire script with:

filename_time2=`date --date='yesterday' +%Y-%m-%d`
cd /location/of/the/files/to/copy
cp server.log-$filename_time2* ../archive/new
exitcode=$?
echo copying attempted
exit $exitcode

but, at least it will give you a non-zero exit code if it failed to copy one or more files successfully.

The $( command ) form of command substitution is preferred over the ` command ` form unless you are using a 1970's Bourne shell that doesn't accept the preferred form.

1 Like

Thank you very much Don Cragun and apmcd47 . I made a mistake while testing the code. The code mentioned by Don Cragun is working perfectly.
Many thanks for your quick help.