7

I wrote the following script:

for filename in `find . -name '*'.cpp | grep $IN_REGEX | grep -v $OUT_REGEX`
do
    echo "Output file is $OUTPUT_FILE"
    count=`git log --pretty=format: --name-only $filename | grep -v ^$ | wc -l`
    echo "$count    $filename" >> $OUTPUT_FILE
done

But nothing gets written into the output file.

Please note:

  1. I have set the values for OUTPUT_FILE, IN_REGEX and OUT_REGEX.
  2. The code inside the loop is being executed. I checked this with an sh -x invokation.
  3. When I remove the >> $OUTPUT_FILE I get the output.
  4. I tried a touch $OUTPUT_FILE inside the script and that is working fine.

Can someone please point out what is my mistake here?

9
  • Can you move the >>$OUTPUT_FILE to the end of the loop, i.e. done >>$OUTPUT_FILE?
    – ott--
    Commented Mar 1, 2013 at 12:37
  • maybe you dont have permission on the dir to redirect the file. So you maybe running it as sudo. sudo touch will work. but sudo echo "string" >> log.txt wont work. Can you add the permission in that dir to the question and how you are running the script.
    – bagavadhar
    Commented Mar 1, 2013 at 12:47
  • Ashwin, even a normal touch is working. Did not need a sudo
    – Karthick S
    Commented Mar 1, 2013 at 12:53
  • 1
    From your two recent questions, I'd bet your script has some carriage return characters as if coming from a system where line ending is with CRLF. Try dos2unix or d2u on the files to convert to Unix line ending. See the output of cat -vte on the file to confirm. Commented Mar 1, 2013 at 13:35
  • Stephane, my script does not use any input files. All the values required (IN_REGEX, OUT_REGEX and OUTPUT_FILE) are set in the script itself. There seems to be something that is preventing this script from writing to the filesystem. I have checked the permissions, the space availability and also if touch works. All three don't show any problem.
    – Karthick S
    Commented Mar 1, 2013 at 14:41

2 Answers 2

3

Does $OUTPUT_FILE exist? What are its permissions (ls -l $OUTPUT_FILE, getfacl $OUTPUT_FILE)? How many times is the echo "Output file..." executed? (I'd put that one outside the for, but it's your call)?

(I'm suspecting your find ... pipeline doesn't return anything)

6
  • I tried with and without the file. Also with an echo outside the loop. It did not work as expected. A touch works anywhere though.
    – Karthick S
    Commented Mar 1, 2013 at 12:56
  • 2
    Again, this just means that your loop just does nothing. Something this fundamental isn't broken.
    – vonbrand
    Commented Mar 1, 2013 at 13:04
  • 1
    Perhaps you have the same mistake as this question in setting the regexps?
    – vonbrand
    Commented Mar 1, 2013 at 13:07
  • -rw-r--r-- These are the permissions on the file and the ownership is with my account.
    – Karthick S
    Commented Mar 1, 2013 at 14:19
  • By the way, the other question was also mine. Something that I resolved by removing the " around the REGEX values.
    – Karthick S
    Commented Mar 1, 2013 at 14:19
0

Here are some ideas that might help you troubleshoot this:

  • Rather than redirect stanard out to a the file, pipe it to tee and include your file. Hopefully you should see the output on stdout (as well as have it go to $OUTPUT_FILE). E.g.:

    echo "$count $filename" | tee $OUTPUT_FILE

  • Use an absolute path for $OUTPUT_FILE, not a relative path so that it's not dependent on where you invoke the script. If you're using relative you may not be looking in the right place for the output file.

  • Continue to invoke the script with -x so you can see exactly what's going on when you run it. Make sure the value of $OUTPUT_FILE is set at the time of redirection.

  • If you're not committed to using sh, you could try your script in bash. You could then make use of some of the bash options using the set builtin (see help set). When developing a script it can be useful to do a 'set -e' to have the script exit if something returns a non-zero exit status. You might also need to play with the status of pipefail. So to help debug you could put this at the top of your script:

    set -x
    set -e
    # Optionally:
    set -o pipefail
    

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .