Fabric is blocking command with pty=False - python

I'm trying to start a remote service with fabric and as pointed by this question my command is:
sudo('service jboss start', pty=False)
but unfortunately this command hangs on my terminal and I'm not able to close the fabric command, even with CTRL+C.
The only way I could find to workarround this issue is with a timeout option but if I have more tasks after that they don't run because the timeout is raised and the fab process is exited with an error.
Am I doing something wrong?

It's most likely related to these two FAQ points:
http://docs.fabfile.org/en/1.7/faq.html#init-scripts-don-t-work
http://docs.fabfile.org/en/1.7/faq.html#why-can-t-i-run-programs-in-the-background-with-it-makes-fabric-hang

Related

run bash script in background with process name

Got a script for activating a python venv and running a server in the background, but right now I am trying to keep the pid when I start the process and then kill the process with pid after I am done. However, it is not all the time is gets killed.
My question is, can I run the process with a name, then killing it by using pkill name after? and how will that look
#!/bin/sh
ROOT_DIR=$(pwd)
activate(){
source $ROOT_DIR/.venv/bin/activate
python3 src/server.py -l & pid=$! # <== This is the process
python3 src/client.py localhost 8080
}
activate
sleep 10
kill "$pid"
printf "\n\nServer is done, terminating processes..."
You can run programs with a specific command name by using the bash buildin exec. Note that exec replaces the shell with the command so you have to run it in a subshell environment like:
( exec -a my_new_name my_old_command ) &
However, it probably won't help you much because this sets the command line name, which is apparently different from the command name. So executing the above snippet will show your process as "my_new_name" for example in top or htop, but pkill and killall are filtering by the command name and will thus not find a process called "my_new_name".
While it is interesting, how one can start a command with a different name than the executable, it is most likely not the cause of your problem. PIDs never change, so I assume that the problem lays somewhere different.
My best guess is that the server binds a socket to listen on a specific port. If the program is not shutdown gracefully but killed the port number remains occupied and is only freed by the kernel after some time during some kind of kernel garbage collect. If the program is restarted after a short period of time it finds the port already been occupied and prints a misleading message, that says it is already running. If that is indeed the cause of your problem I would strongly consider implementing a way to graceful shutdown the server. (may be already closing the socket in a destructor or something similar could help)
I think you should have to use systemd for this case:
https://github.com/torfsen/python-systemd-tutorial

Git bash "Watching for file changes with StatReloader" stuck and never loads

I have setup a Django project on a virtual environment on my PC. When using the command
python manage.py runserver 0.0.0.0:8000
Bit Bash stops doing anything and I have to end the program to start over. I have waited several minutes and when I end the session, a dialogue says:
Processes are running in session:
WPID PID COMMAND
14904 1534 c:\Users\mine\AppData\Loca
Close anyway?
I have looked at every related question to this and tried every solution but I cannot get this to work, on or off the virtual environment.
Not sure if this applies, but I also noticed that in my task manager, python3.9.exe appears twice when trying to start the server. The status says running, and the PIDs are different numbers.
This is because something already running on port 8000. You can run the Django server by hosting on another port like 8080 but, you can also kill the already running task on the port. Follow the link to know how exactly you can kill any running process.
It is highly likely that another application is running using the port 8000. Try running the server using another port, say 8088 and share if the same issue persists.
To run on specific port kill all pids which is showing you on Git bash
(ps -ef)... kill them using (kill -9 pid_no)... then run your runserver command.
Ex:
ps -ef
kill -9 123
I ended up paying someone to fix this. Here is the conversation I had with the person who found the issue. Hope this helps someone out there.
Also, I noticed sometimes it still does freeze up on the watching for file changes with StateReloader until I go the browser and type in http://localhost:8000/. Once I do that the rest of the text loads and my browser shows The install worked successfully! Congratulations!
it works, what did you do?
- We have existing processes on port 8000.I think, you had the server running and kept trying over and over. So, I killed process using 8000 port.
- Next, I run Django project again.
- So, now it's working well.
ok. Can you tell me what you did at the start to make it work? Or was it always working?
- I started git bash session again when I started. Maybe git bash session had problems.
But this was going on for a day, I restarted the computer several times and restarted git bash. Same issue.
You must have done something.
- Sorry, I didn't do anything except restart git bash
how did you restart it?
- right click top of window, select NEW
How do I turn server off?
- press Ctrl + C
- And you didn't quit the server exactly before. Maybe you closed git bash directly and server was still live
- So, we had many 8000 ports.
Ok. How can I see what is on that port now?
- You can use this cli
- netstat -ano | findstr :<PORT>
- We don't have running 8000 port now.
I have never found solutions to this problem even with killing ports, changing port etc.
It never display the following part:
Starting development server at http://127.0.0.1:8000/
However, when I use the Git Bash terminal include into vscode, it displays the url.
Terminal > New Terminal > then:
Result :
python manage.py runserver 127.0.0.1:8080

How can I keep a python script on a remote server running after closing out of SSH?

I've coded a stock trading bot in Python3. I have it hosted on a server (Ubuntu 18.10) that I use iTerm to SSH into. Wondering how to keep the script actively running so that when I exit out of my session it won't kill the active process.
Basically, I want to SSH into my server, start the script then close out and come back into it when the days over to stop the process.
You could use nohup and add & at the end of your command to safely exit you session without killing original process. For example if your script name is script.py:
nohup python3 script.py &
Normally, when running a command using & and exiting the shell afterwards, the shell will terminate the sub-command with the hangup signal (kill -SIGHUP <pid>). This can be prevented using nohup, as it catches the signal and ignores it so that it never reaches the actual application.
You can use screen
sudo apt-get install screen
screen
./run-my-script
Ctrl-A then D to get out of your screen
From there you will be able to close out your ssh terminal. Come back later and run
screen -ls
screen -r $screen_running
The screen running is usually the first 5 digits you see after you've listed all the screens. You can see if you're script is still running or if you've added logging you can see where in the process you are.
Using tmux is a good option. Alternatively you could run the command with an & at the end which lets it run in the background.
https://tmuxcheatsheet.com/
I came here for finding nohup python3 script.py &
Right solution for this thread is screen OR tmux. :)

Django server is still running after CONTROL-C

I start Django server with python manage.py runserver and then quit with CONTROL-C, but I can still access urls in ROOT_URLCONF, why?
Probably you left another process running somewhere else.
Here is how you can list all processes whose command contains manage.py:
ps ax | grep manage.py
Here is how you can kill them:
pkill -f manage.py
Without seeing your script, I would have to say that you have blocking calls, such as socket.recv() or os.system(executable) running at the time of the CTRL+C.
Your script is stuck after the CTRL+C because python executes the KeyboardInterrupt AFTER the the current command is completed, but before the next one. If there is a blocking function waiting for a response, such as an exit code, packet, or URL, until it times out, you're stuck unless you abort it with task manager or by closing the console.
In the case of threading, it kills all threads after it completes its current command. Again, if you have a blocking call, the thread will not exit until it receives its response.
just type exit(), that is what I did and it worked

Python BaseHTTP gets struck while starting nginx or other services

I am using BaseHTTP since its very simple. Please advice if I'm using it wrong.
if self.path.endswith("nginxstart"):
xxxxxx
status=os.system("/home/karthik/nginx/nginx-1.0.4/sbin/nginx"); #tried ls -l and works
self.wfile.write("nginx restarted")
nginx gets started but doesn't write "nginx restarted" to browser until I kill the python server.
When I do netstat -anp | grep 'nginx's pid' there are two listening ports :
python server was listening (port 8000: which I have killed)
on which nginx was supposed to be running.
Works great if i run simple shell commands os.system("ls -l") and so on.
Works great if I run the same as a normal python script, not as a web server.
Tried starting some other services also not working.
I tried with try catch, catch part is not getting executed.
The browser is in connecting/receiving state forever.
Any help on this please ?
Your code is stuck because os.system block until the command is finished. So if the nginx command is not going to background, the process will not end, and your code will stuck.
An alternative is to use subprocess module:
from subprocess import Popen
# start a new command
cmd = Popen("/home/.../nginx", shell=True)
# you can regulary check if the command is still running with:
cmd.poll()
if cmd.returncode is None:
print "process is still running !"
else:
print "process exited with code %d" % cmd.returncode
# or even kill it
cmd.kill()

Categories

Resources