'Get user input for a Python script ran from a bash script
Tldr at the end
I have a simple Python script with a few functions, let's give this main.py
as a minimal example :
import sys
def userAdd():
var = input("Please type any input: ")
print("My input is", var)
if __name__ == '__main__':
globals()[sys.argv[1]]()
When I call :
python main.py userAdd
Everything works fine. The script runs, the Python console asks me for my input, and then edits the JSON file. Now I want this script to be executed everytime I edit a text file, let's say myfile.txt
which for now only has this line :
foo
For this, I use this bash script and changed the "RUN COMMAND"
line with python main.py userAdd
(let's call it update.sh
):
#!/bin/bash
### Set initial time of file
LTIME=`stat -c %Z ./myfile.txt`
while true
do
ATIME=`stat -c %Z ./myfile.txt`
if [[ "$ATIME" != "$LTIME" ]]
then
python main.py userAdd
LTIME=$ATIME
fi
sleep 1
done
My problem happens here. Everytime the Python script is called from the Bash script, the input prompt shows up. I enter a value, and I get a bash : <input> command not found
, which means the current tty I'm using isn't Python, but Bash
$ chmod +x update.sh
$ ./update.sh &
$ echo "bar" >> myfile.txt
$ Please type any input: test
bash: test : command not found
I tried a few things (using /usr/bin/env and /dev/tty or <&1, or using python -i
).
tldr; My Python script asks for a user input to update a file. When I run it directly from my bash terminal (python main.py myfunction), it works fine. When I run this Python script from a Bash script (which contains this same python [...] line) and type my input, I get a bash <input> command not found
. This means that the terminal isn't Python's but Bash's. How can I get a Python terminal which will accept my input in this case ?
Solution 1:[1]
For anyone who might be facing the same issue, here's how I solved it : I edited the line from update.sh
invoking the Python script like so :
#!/bin/bash
### Set initial time of file
LTIME=`stat -c %s ./myfile.txt`
while true
do
ATIME=`stat -c %s ./myfile.txt`
if [[ "$ATIME" >= "$LTIME" ]]
then
/usr/bin/konsole -e /usr/bin/bash -c './main.py userAdd'
LTIME=$ATIME
fi
sleep 1
done
So this line ties me up to a specific terminal, but I think this could easily be bypassed by more advanced Linux users.
Then, when I run the script using ./update.sh &
and add this line to a cron, everytime I edit and close the file, a new terminal runs, asks for the input prints the results then closes (although for the sake of the example a wait()
command should be added after the print()
).
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Emmanuel Daveau |