Subprocess.cal issue - FileNotFoundError: [WinError 2]

I was using the script successfully when I need to check if some PC is on-line. I used command ‘ping’ for subprocess.call
This time I need to check account of User to check if it’s active.
Command that I run is: net user /domain USER
It works fine from command line but failed in a script.
Could someone help me with it?
Thanks

#from subprocess import call

import subprocess
import time
import winsound
import datetime



x = subprocess.call(["net user /domain USER|grep -i active"])

# Clear 25 lines of screen for convinience
def clear():
    print('\n' * 25)

clear()

while True:
    if x == 0:
        print ("********************\n")
        print ("\n")
        print ("OK")
        print (datetime.datetime.now().strftime('%Y-%m-%d %H:%S'))
        winsound.Beep(500,5000)
        exit()
    else:
        time.sleep(30)
        print ("Wait")
        x = subprocess.call(["net user /domain USER|grep -i active"])
        clear()


I see this error:

python WhileLoop_account.py
Traceback (most recent call last):
  File "U:\Scripts\WhileLoop_account.py", line 10, in <module>
    x = subprocess.call(["net user /domain USER|grep -i active"])
  File "C:\Python310\lib\subprocess.py", line 345, in call
    with Popen(*popenargs, **kwargs) as p:
  File "C:\Python310\lib\subprocess.py", line 966, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "C:\Python310\lib\subprocess.py", line 1435, in _execute_child
    hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
FileNotFoundError: [WinError 2] The system cannot find the file specified

Check the docs for the shell=True option. So that you can pass your command string.

Reference on Stack Overflow:

Folks, Thanks so much … providing this parameter fixed the issue.
One more (minor) thing I hit with my script. I want to have the option to comment/uncomment account that I am interested
I am using ‘real’ account like this:

Account = "vhabhsabjoe"
#Account= "vhabhsabnick"

x = subprocess.call('net user /domain Account', shell=True)

but it failed to pass Account to sub process. Sounds like my syntax is wrong …
Here’s the error:

python WhileLoop_account.py
The request will be processed at a domain controller for domain v01.med.va.gov.

The user name could not be found.

Just having Account in the string means the actual letters Account, not that variable - just like how you don’t get an error because there isn’t a net variable or a user variable or a domain variable in the program.

A simple command like what you’ve shown could be done better using separate arguments, as shown in the links I provided before. Thus, subprocess.call(['net', 'user', '/domain', Account]). (Notice that Account has no quotes because we want to put that variable into the list, but the others should be actual strings.)

However, to learn the general technique for creating the string, please see:

1 Like

Thanks so much!
I’m all set now

Originally shell=True was needed because the output was piped to grep via "net user /domain USER|grep -i active". If you’re not piping to grep, you could also use subprocess.call(f'net user /domain {Account}').

If an argument list is passed, such as ['net', 'user', '/domain', Account], then on Windows subprocess.list2cmdline() is internally called by subprocess.Popen in order to convert the list into a command-line string, according to the rules used by WinAPI CommandLineToArgvW() and the C runtime’s argv parsing. However, programs are free to use their own command-line parsing rules (e.g. as Cygwin programs do), in which case passing a command-line string may be the only viable solution.

Folks,
Thanks for suggestions.
Now my program is working but I hit another … while minor but still related issue.
I am using bash from MobaXterm app.
My file is located here: /cygdrive/u/Scripts/WhileLoop_account.py
When I run it from the directory /cygdrive/u/Scripts it works fine
When I run it from other directory it failed with this error:

python /cygdrive/u/Scripts/WhileLoop_account.py
C:\Python310\python.exe: can’t open file ‘U:\cygdrive\u\Scripts\WhileLoop_account.py’: [Errno 2] No such file or directory

When I run it and provide another path it works fine.
python u:/Scripts/WhileLoop_account.py
Question: how I could fix it?

Windows Python only supports Windows drive-letter paths, UNC paths, and relative paths. In Windows, the path “/cygdrive/u/Scripts/WhileLoop_account.py” is a relative path that refers to the “/cygdrive” directory on the drive or UNC share of the current working directory. For example, if the working directory is “C:\Temp”, then the relative path resolves to “C:\cygdrive\u\Scripts\WhileLoop_account.py”.

Cygwin applications don’t use drives, but they reserve the “/cygdrive” directory for accessing Windows drives, such as “/cygdrive/u” in place of Windows “U:\”. You can convert to Windows form using the cygpath command, e.g.

python "$(cygpath -w /cygdrive/u/Scripts/WhileLoop_account.py)"

Or switch to using a Cygwin build of Python instead of Windows Python.

2 Likes

Thanks so much for explanation

Well … I realized that I missed important thing in my script. The goal of the script is to figure out if account is Active. For that reason I still need to ‘grep’ for this string ‘Account active Yes’
Hence I modified my original script and put ‘grep’ in subprocess.call but it stopped to work.
I’ve got this error and it’s looping:
python WhileLoop_account-TEST.py
The system cannot find the path specified.
**
Here is my script now:

import subprocess
import time
import winsound
import datetime


Account = 'Joe'
#Account = 'Jen'

x = subprocess.call(["'net', 'user', '/domain', Account | grep 'Account active               Yes'"], shell=True)

# Clear 25 lines of screen for convinience
def clear():
    print('\n' * 25)

clear()

while True:
    if x == 0:
        print ("********************\n")
        print ("\n")
        print ("Account " + Account + " is ACTIVE")
        print (datetime.datetime.now().strftime('%Y-%m-%d %H:%S'))
        winsound.Beep(500,5000)
        exit()
    else:
        time.sleep(30)
        print ("Still trying ... WAIT!!")
        x = subprocess.call(["'net', 'user', '/domain', Account | grep 'Account active               Yes'"], shell=True)
        clear()

Could some help me with the script?
Thanks

Always use a command-line string with shell=True. For example:

x = subprocess.call(f'net user {Account} | grep -E "Account active[[:space:]]+Yes"', shell=True)
1 Like

Don’t use grep. You have python!

What i do is run commands and get their output.
Then i use python to look for the information i am after.
Something like this:


p = subprocess.run(f'net user {Account}’, capture_output=True)
If ‘Active’ in p.stdout:
       print(‘its is active’)

1 Like

If the user’s preferred UI language is English, then “Active” will always be in the output, qualified by “Yes” or “No”. When I get the time, I’ll implement this for Susja independent of the configured UI language, using PyWin32 and/or ctypes.

Thank you very.
It looks that now I’m all set

Well in my case I see only two values: Yes or Locked
Usually automatic unlocks happens in about a half hour.
Hence my goal is to visually and vocally notified when account gets unlocked.
Thanks again for your help and the current script serves my goal

(Attachment me.bmp is missing)