Search code examples
pythonpython-2.7cmdfindpsexec

Issue using find with psexec


I am having an issue with getting psexec and find to play nicely together in my python function. Here is the function that I am trying to get to work:

def CountString(address, file, findstr):

    cmd_line = r'psexec \\{0} cmd /c find /c "{1}" "{2}"'.format(address, findstr, file)
    print cmd_line

    myP = subprocess.Popen(cmd_line, shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE)

    out = timeout(myP.communicate, (), {}, 30, (None, None))

    return out

Here is an example of how I am testing the function:

test = CountString(r'RemotePC', r'c:\directory\File to Count.txt', r'String to count')
print test

In my first snippet of code I have added a print cmd_line in order to verify that the cmd line looks correct, and from what I can tell it does. If I run the function with my example input it returns:

psexec \\RemotePC cmd /c find /c "String to count" "c:\directory\File to Count.txt"

I can even copy and paste the output of print cmd_line into a cmd window and it works as expected:

C:\>psexec \\RemotePC cmd /c find /c "String to count" "c:\directory\File to Count.txt"

PsExec v1.97 - Execute processes remotely
Copyright (C) 2001-2009 Mark Russinovich
Sysinternals - www.sysinternals.com



---------- c:\directory\File to Count.txt: 3600
cmd exited on RemotePC with error code 0.

C:\>

But for some reason I cannot get the python function to return a result, it will just sit there and hang if I do not have it timeout.

I have also tried changing my syntax of cmd_line to add "" around find /c "{1}" "{2}":

cmd_line = r'psexec \\{0} cmd /c "find /c "{1}" "{2}""'.format(address, findstr, file)

Again the output of print cmd_line works from the cmd line itself, but will not consistently work in python.

One strange thing I have noticed is that this will return what I want maybe 1 out of 25 tries. But when I run it again against the same remote PC and the same file, it fails.

Note: I am not opposed to using something besides find if there is something else that will return a count of the string I am trying to find in the file. But I do need to use psexec, or something that will allow me to execute the command remotely on an XP machine, because the files that I am attempting to count the string from are very large and will return results over a few thousand.


Solution

  • I found a work around! I am still using find, but now instead of using it directly, I pipe it the results from findstr.

    Here is what my cmd_line looks like now:

    cmd_line = r'psexec \\{0} cmd /c "findstr /c:"{1}" "{2}" | find /v /c """'.format(address, findstr, file)