I am trying to understand how to execute a command/program using python subprocess module & respond to the prompt by giving input.
Sample Program Program1.py which can take multiple input's:
arr1=[]
username = input("Enter your username1 : ")
password = input("Enter your password1 : ")
arr1.append((username,password))
username = input("Enter your username2 : ")
password = input("Enter your password2 : ")
arr1.append((username,password))
username = input("Enter your username3 : ")
password = input("Enter your password3 : ")
arr1.append((username,password))
username = input("Enter your username4 : ")
password = input("Enter your password4 : ")
arr1.append((username,password))
for item in arr1:
print("username:",item[0],"Password:",item[1])
I have written another program called Execute_Program1.py
import subprocess
proc = subprocess.Popen('python Program1.py',stdout=subprocess.PIPE,stderr=subprocess.PIPE,stdin=subprocess.PIPE,shell=True,universal_newlines=True)
print(proc.poll())
while proc.poll() is None:
print(proc.stdout)
proc.stdin.write('inputdata\n')
But this program is not able to execute the Program1.py. I have read many posts related to this. As per the information I have got proc.poll() return's None then the command executed by Popen is still active.
But my program is giving the following output:
None
<_io.TextIOWrapper name=4 encoding='cp1252'>
I am using Python version 3.7.4. Could anyone please help me with some inputs where I am doing mistake?
Thanks in advance.
I could not get it to work with subprocess at this time but I wanted you to have an ASAP working solution using the os module in case you need this quickly and are not absolutely required to use the subprocess module...
First add this line to the end of Program1.py, with no indentation, to prevent the command window from exiting before you have a chance to see the output:
input("Press <enter> to continue")
Next, replace your entire code in Execute_Program1.py with the following:
import os
os.system("python Program1.py 1")
This worked beautifully in Python 3.8.1 on win10pro.
With the help of https://stackoverflow.com/a/22391379/9088305 and APT command line interface-like yes/no input? I have been able to build a little script that wait for a while but can be interrupted by pressing enter.
import sys, select, os, time
from distutils.util import strtobool
for i in range(100):
sys.stdout.write("\r")
sys.stdout.write("Wait for {:2d} seconds. Press Enter to continue".format(i))
sys.stdout.flush()
time.sleep(1)
if sys.stdin in select.select([sys.stdin], [], [], 0)[0]:
check = 0
while not check:
userin = raw_input("Are you sure you want to continue? (yes/no)")
try:
bool = strtobool(userin)
if bool:
check = 1
break
else:
print("Let's continue then")
time.sleep(1)
break
except ValueError:
check = 0
print("Choose either yes or no, please")
if check == 1:
break
print "\nDone!"
However, upon execution, it will alway give the question once, with an ""Choose either yes or no, please" after that:
Are you sure you want to continue? (yes/no)Choose either yes or no, please Are you sure you want to continue? (yes/no)
I haven't been able to figure out why this is. Can someone help me out? So that I can just get "Are you sure you want to continue? (yes/no)" once and I can put in yes or no.
Thanks in advance!
I'm trying to make a password system for a program. I have the first half working so when I punch in the code it opens my file. After that the program asks for the password again instead of moving on to the next module which is supposed to close the file. Here's what I have
import os
while True:
choice = int(input("Enter Password: "))
if (choice>=1124):
if choice ==1124:
try:
os.startfile('C:\\restriced access')
except Exception as e:
print (str(e))
while True:
choice = int(input("Close? (y/n): "))
if (choice<='y'):
if choice =='y':
os.system('TASKKILL /F /IM C:\\restriced access')
I want it to kind of appear as an "if/then" kinda statement. For example if the password is entered correctly it opens the file `os.startfile('C:\restriced access') then points to the next module to give the option to close.
"While True" just keeps looping infinitely. As soon as you open the file it'll go back to the beginning of that loop and ask for your password again. If you want it to break from that loop if they get the password correct you need to add a "break" after your startfile line. I'm also not sure why you check their password twice. If you want it to exit the loop after attempting to open the file whether it succeeds or not, add a "finally" block after your exception handler.
while True:
choice = int(input("Enter Password: "))
if (choice>=1124):
if choice ==1124:
try:
os.startfile('C:\\restriced access')
break
except Exception as e:
print (str(e))
Your while loop is while True:. This will never exit unless you explicitly exit from it. You want to add a break in it like so:
os.startfile('C:\\restriced access')
break
Great to see you learn python.
The reason is because the while loop doesn't have a break in it.
Then again avoid opening files in a loop.
Also the nested if makes it hard to debug.
Also checkout pep8.
havent made any code changes.
import os
while True:
choice = int(input("Enter Password: "))
if (choice<1124):
continue
if choice ==1124:
try: os.startfile('C:\\restriced access')
break
except Exception as e:
print (str(e))
break
while True:
choice = input("Close? (y/n): ")
if (choice=='y'):
break
So the program I'm trying to make is that an user can enter a path WHICH HAS TO BE CORRECT to continue. I thought that I would make a simple prompt to tell the user it is either a valid path or not.
This is my prompt code:
if Path.find("Global") == -1:
continue
else:
print "Not a valid path."
Of course I can't use continue in there but I just don't get how to make this prompt as a loop. The idea was that if the Path contains the word "Global" the program continues with another action and if it doesn't contain the word it will tell the user a message and tell the program to stop (break).
def get_path():
Path = raw_input("Please select the correct path: ")
if Path.find("Global") == -1:
# "Tell the user a message and tell the program to stop".
print('{0} is not a correct path.'.format(Path))
return
# "the program continues with another action."
print('{0} is a correct path.'.format(Path))
You can break the loop unless your input matches condition, like this:
while True:
if 'Global' in raw_input('Enter a valid path: '):
continue
else:
print 'Not a valid path.'
break
Try this:
Path = raw_input("Please enter a valid Path")
while Path.find("Global") == -1:
print "This is not a valid Path."
Path = raw_input("Please enter a valid Path")
This question already has answers here:
Getting a hidden password input
(6 answers)
Closed 7 months ago.
This post was edited and submitted for review 3 months ago and failed to reopen the post:
Original close reason(s) were not resolved
Is there a way in Python to convert characters as they are being entered by the user to asterisks, like it can be seen on many websites?
For example, if an email user was asked to sign in to their account, while typing in their password, it wouldn't appear as characters but rather as * after each individual stroke without any time lag.
If the actual password was KermitTheFrog, it would appear as ************* when typed in.
I am not asking about how to disable echoing characters to the screen, which is what Python's getpass.getpass() module does. I specifically want the feature where asterisks appear in response to key presses, which getpass doesn't do.
There is getpass(), a function which hides the user input.
import getpass
password = getpass.getpass()
print(password)
If you want a solution that works on Windows/macOS/Linux and on Python 2 & 3, you can install the pwinput module (formerly called stdiomask):
pip install pwinput
Unlike getpass.getpass() (which is in the Python Standard Library), the pwinput module can display *** mask characters as you type. It is also cross-platform, while getpass is Linux and macOS only.
Example usage:
>>> pwinput.pwinput()
Password: *********
'swordfish'
>>> pwinput.pwinput(mask='X') # Change the mask character.
Password: XXXXXXXXX
'swordfish'
>>> pwinput.pwinput(prompt='PW: ', mask='*') # Change the prompt.
PW: *********
'swordfish'
>>> pwinput.pwinput(mask='') # Don't display anything.
Password:
'swordfish'
Unfortunately this module, like Python's built-in getpass module, doesn't work in IDLE or Jupyter Notebook.
More details at https://pypi.org/project/pwinput/
If you're using Tkinter:
# For Python 2:
from Tkinter import Entry, Tk
# For Python 3
from tkinter import Entry, Tk
master = Tk()
Password = Entry(master, bd=5, width=20, show="*")
Password.pack()
master.mainloop()
In the shell, this is not possible. You can however write a function to store the entered text and report only a string of *'s when called.
Kinda like this, which I did not write. I just Googled it.
You can do this:
# if getch module is available, then we implement our own getpass() with asterisks,
# otherwise we just use the plain boring getpass.getpass()
try:
import getch
def getpass(prompt):
"""Replacement for getpass.getpass() which prints asterisks for each character typed"""
print(prompt, end='', flush=True)
buf = ''
while True:
ch = getch.getch()
if ch == '\n':
print('')
break
else:
buf += ch
print('*', end='', flush=True)
return buf
except ImportError:
from getpass import getpass
first install the library:
pip install stdiomask
note that you install std io mask not studiomask...
And then the code is:
password = stdiomask.getpass() # It will ask to enter password and display * on the screen
print(password)
This is the output:
Password: *****
google
while using getpass in python, nothing is indicated to show a password input.
this can be resolved by this simple solution:
just copy the ‘getpass_ak.py’ module provided in the link to python’s Lib folder.
https://starrernet.wixsite.com/analytix/python-coder
use the following code:
import getpass_ak
a = (getpass_ak.getpass('password: '))
this will add * to your password inputs.
For anyone who would actually want to have asterisks appear, here's an improvement on Tigran Aivazian's answer. This version imports the built-in msvcrt.getch, adds cases for different line endings when hitting 'Enter/Return', and includes logic to support Backspace, as well as Ctrl+C (KeyboardInterrupt):
try:
from msvcrt import getch
def getpass(prompt):
"""Replacement for getpass.getpass() which prints asterisks for each character typed"""
print(prompt, end='', flush=True)
buf = b''
while True:
ch = getch()
if ch in {b'\n', b'\r', b'\r\n'}:
print('')
break
elif ch == b'\x08': # Backspace
buf = buf[:-1]
print(f'\r{(len(prompt)+len(buf)+1)*" "}\r{prompt}{"*" * len(buf)}', end='', flush=True)
elif ch == b'\x03': # Ctrl+C
raise KeyboardInterrupt
else:
buf += ch
print('*', end='', flush=True)
return buf.decode(encoding='utf-8')
except ImportError:
from getpass import getpass
Please feel free to suggest any other changes, or ways to improve this; I hacked the changes together pretty quickly, especially with the Backspace logic.
I have combined the answers of #Tigran Aivazian and #Ahndwoo into fully working solution:
! additional code for the backspace {b'\x08', b'\x7f'}: # Backspace is added
for the Ctrl+C combination the silent return is used. The raise KeyboardInterrupt is commented now, but can be uncommented for raise the error.
# if getch module is available, then we implement our own getpass() with asterisks,
# otherwise we just use the plain boring getpass.getpass()
try:
from getch import getch
def getpass(prompt):
"""Replacement for getpass.getpass() which prints asterisks for each character typed"""
print(prompt, end='', flush=True)
buf = b''
while True:
ch = getch().encode()
if ch in {b'\n', b'\r', b'\r\n'}:
print('')
break
elif ch == b'\x03': # Ctrl+C
# raise KeyboardInterrupt
return ''
elif ch in {b'\x08', b'\x7f'}: # Backspace
buf = buf[:-1]
print(f'\r{(len(prompt)+len(buf)+1)*" "}\r{prompt}{"*" * len(buf)}', end='', flush=True)
else:
buf += ch
print('*', end='', flush=True)
return buf.decode(encoding='utf-8')
except ImportError:
from getpass import getpass
password = getpass('Enter password: ')
print(password)
My own suggestion is -- DO NOT DO IT!
Don't reinvent the wheel, use a password helper if you want 'stars'
Instead do something like the following pseudo-code... If the TTY_ASSPASS environment variable is set -- call that password helper. There are a number available, including "systemd-ask-password" If there is a TTY - fall back to read no echo (getpass.getpass()) If there is no TTY, - fall back just read STDIN with rstrip()
This not only lets the user select a password input program (via an environment variable (or some other confuguration), but also lets them substitute for other sources of passwords, like GUI input, or collecting password from a pre-opened keyring password daemon, or elsewhere
Don't restrict or otherwise limit where passwords come from!
For notes on password helpers see.. https://antofthy.gitlab.io/info/crypto/passwd_input.txt
For a shell script password helper https://antofthy.gitlab.io/software/#askpass_stars
Looks like Andrei Krivoshei answer has already made a start on that, resulting in something very similar, but still in its infancy.
You may want to check getpass function.
Prompt the user for a password without echoing. The user is prompted
using the string prompt, which defaults to 'Password: '. On Unix, the
prompt is written to the file-like object stream. stream defaults to
the controlling terminal (/dev/tty) or if that is unavailable to
sys.stderr (this argument is ignored on Windows).
Note: This module mimics unix password prompts and does not show asterisks.
Usage:
import getpass
getpass.getpass()