4

I want to count how many lines of code I have written.

Here is the Python code:

import os
import sys

EXT = ['.c','.cpp','.java','.py']

def main():
    l = []
    if os.path.isdir(sys.argv[1]):
        for root, dirs, files in os.walk(sys.argv[1]):
            l.extend([os.path.join(root, name) for name in files])
    else:
        l.append(sys.argv[1])

    params = ["'"+p+"'" for p in l if os.path.splitext(p)[1] in EXT]

    result = os.popen("wc -l %s "%" ".join(params)).read()
    print result

if __name__ == '__main__':
    main()

Before this, it was running as expected. But today, it give me this error:

sh: 1: Syntax error: Unterminated quoted string

I don't know what happened.

4
  • 2
    How are you executing this script? Commented Aug 31, 2013 at 3:17
  • @Johnsyweb python program.py . Commented Aug 31, 2013 at 3:42
  • 1
    Try adding print params before your popen line. Do any of the elements in params have a single quote in them? Commented Aug 31, 2013 at 5:09
  • 2
    you should also consider using the newer subprocess module instead of popen Commented Aug 31, 2013 at 5:52

3 Answers 3

5

Your Python script is missing a shebang line. Add the following to the top of your file:

#!/usr/bin/env python

Then you should be able to run the following, assuming your script is at /path/to/your_script.py and it has the executable bit set:

/path/to/your_script.py arg1 arg2 [...]

Alternatively:

python /path/to/your_script.py arg1 arg2 [...]

Update following comments

I suspect what has changed is that a source file containing a ' in its name has been added to the directory you are checking and the shell is choking on this.

You could add the following function to your program:

def shellquote(s):
    return "'" + s.replace("'", "'\\''") + "'"

[Lifted from Greg Hewgill's answer to How to escape os.system() calls in Python? .]

And call it like this:

params = [shellquote(p) for p in l if os.path.splitext(p)[1] in EXT]
Sign up to request clarification or add additional context in comments.

5 Comments

@maemual: The same "wrong" or a different "wrong"? What is the output of which python (and python --version)?
which python /usr/bin/python, python --version 2.7.3
To be clear, the first line is to be added to the top of the script itself; the second and third are commands to be executed from the shell. And see this question and my answer for discussion of the #!/usr/bin/env trick; the alternative is #!/usr/bin/python
@maemual: Then I have a new theory and have updated my answer.
Yes, it's the true problem.THX!
1

@Johnsyweb's updated answer seems to have the correct diagnostic, but the correct fix is to not use a shell to invoke wc. Try something like this instead:

cmd = ['/bin/wc', '-l'] # Need full path!
[cmd.extend(p) for p in l if os.path.splitext(p)[1] in EXT]
result = os.popen2(cmd).read()

Note that the subprocess module is the recommended solution now. Switching to that requires a less intrusive change to your current code, though; see http://docs.python.org/2/library/subprocess.html#replacing-os-popen-os-popen2-os-popen3

2 Comments

Nice fix, but why are you creating a list comprehension here?
@Johnsyweb: Lazy copy/paste; not at my computer so didn't want to change more than absolutely necessary. Feel free to edit, or adopt into your answer.
0

Looks like your Python program was parsed like a shell script. Add something like this at the header to indicate where your Python is:

#!/usr/bin/python

or you just run python a.py.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.