0

I'd like to write a bit of code that looks like this:

while ( `ls -1 ${JOB_PREFIX}_${job_counter}_*.out | wc -l` > 0 )
   echo "Do something here." 
end

But every time there is no ls -1 ${JOB_PREFIX}_${job_counter}*.csh it gives an annoying ls: No match.

Is it possible to suppress this error message but still pipe STDOUT to wc ? I went through the existing questions on this but most of the answers are either not working on csh or tries to combine STDOUT and STDERR with |& which I do not want.

Vivek V K
  • 1,100
  • 2
  • 15
  • 33

2 Answers2

0

The cleanest way would have been to mute the ls itself, but it is not possible.
You can suppress your entire script, meaning:
If your loops is in a file called myscript.cs and you call your file with some args myscript.cs -arg1 blabla -arg2 bla, add >& to your shell command to redirect stderr to wherever you want. e.g.
myscript.cs -arg1 blabla -arg2 bla >& /dev/null

It's not answering your answer directly, but it should solve your problem.

Edit
Since the comment added that the script should be redirected to another script, you can split your line to two lines:

if `ls -1 ${JOB_PREFIX}_${job_counter}_*.out >& /dev/null` then
while < your while here >
end
endif

user2141046
  • 862
  • 2
  • 7
  • 21
  • Unfortunately this does not solve the problem as the output of the script piped to another script and also sent to a log file, all of which will then have the same problem. I'd really like a solution that would suppress `ls` in effect. – Vivek V K Feb 22 '17 at 12:20
  • take a look at http://stackoverflow.com/questions/42261228/csh-set-no-match-error-wildcard/42384620#42384620 I answered there on a very similar question – user2141046 Feb 23 '17 at 10:05
0

csh and tcsh cannot redirect stderr by itself, one of many reasons you should not use it for scripting.

If you're okay with spawning another shell, you can change JOB_COUNTER into an environment variable and do:

while ( `sh -c '2>/dev/null ls -1 ${JOB_PREFIX}_${JOB_COUNTER}_*.out | wc -l'` > 0 )
   echo "Do something here." 
end

If you want to use a test as a condition in a while loop instead of an expression, you have to get creative.

#!/bin/tcsh -f
set i = 4
while ( 1 )
    if ( $i <= 0 ) break 
    echo hi
    @ i = ($i - 1)
end

In your case, this might look something like: I changed the wc -l to a grep -q . so that we can use the exit status instead of the result printed to stderr.

#!/bin/tcsh -f

set dir_exit_status = 0
while ( $dir_exit_status = 0 )
    ( ls -1 ${JOB_PREFIX}_${job_counter}_*.out | grep -q '.') >& /dev/null
    set dir_exit_status = $status
end
Greg Nisbet
  • 6,710
  • 3
  • 25
  • 65