Run python command from bash ubuntu - python

I have installed odoo 8.0 (formerly openerp) source in my ubuntu 14.04
When i try this command (to run odoo server) from terminal
python odoo.py
it was run normally.
But, how can i know the return value of python command?
i want to see if the command running normally, or
it is raise an exception?
So i can make *.sh file to run that command.
I have tried this code
if [ -f odoo.py ]; then
python odoo.py
rc=$?;
if [ $rc !=0 ]; then
echo "Error when starting odoo-server,"
echo "Odoo-server not started."
else
sleep 1
echo "Odoo-server started."
fi
else
echo "Cannot found odoo.py"
echo "Odoo-server not started."
fi
but, when the command fail
it is always give me this output
Odoo-server started
Any one can help me?

Your spacing is wrong:
if [ $rc !=0 ]; then
Should be:
if [ $rc != 0 ]; then
But that is a text test, an arithmetic test would be:
if [ $rc -ne 0 ]; then
or preferably:
if (( rc != 0 )); then
However, a better way would be:
if python odoo.py
then
sleep 1
echo "Odoo-server started."
else
echo "Error when starting odoo-server," >&2
echo "Odoo-server not started." >&2
fi

Related

daemonizing a python script: What is better? start-stop-daemon or python-daemon

I like to start a python program as a daemon. I checked a bit the internet and came up with two solutions.
The first one is to use start-stop-daemon on something like this
#!/bin/sh
start() {
start-stop-daemon -S -q -m -b -p /var/run/sample.pid --exec /usr/bin/python /bin/sample.py && echo "OK" || echo "Failed"
}
stop() {
start-stop-daemon -K -q -p /var/run/sample.pid
}
case "${1}" in
start)
start
echo "sample service started"
;;
stop)
stop
echo "sample service stopped"
;;
restart)
stop
start
echo "sample service restarted"
;;
*)
echo "usage: $0 {start|stop|restart}"
;;
esac
The second one is to use python-daemon
so I guess we have an extra python file - lets name it "sampleDaemon.py"
import daemon
import sample
with daemon.DaemonContext():
sample()
And a bash script (I am not sure about that - I guess this way):
#!/bin/sh
/usr/bin/python /bin/sampleDeamon.py
What is the best way to do it? What are the limitations? The python-deamon documentation is not that big(or I didn't found it).

pyenv .zshrc producing errors on new set-up

I've been working on setting up virtual environments for the first time, and I'm running into a simple problem, but I'm running into roadblocks.
I've followed the step-by step process to enabling pyenv, and I believe that I have it correct with the exception of adding to the .zshrc file on macOS.
Using zsh, I've added these lines to the code:
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc
When I create a new py file, in Visual Code Studio, I see these errors:
bash: ‘export: command not found
source /Users/cnichols/.pyenv/versions/venv_one/bin/activate
bash: /Users/cnichols/.bash_profile: line 12: syntax error near unexpected token `then'
bash: /Users/cnichols/.bash_profile: line 12: `‘eval “export PATH="/usr/local/Cellar/pyenv-virtualenv/1.1.5/shims:${PATH}"; export PYENV_VIRTUALENV_INIT=1; _pyenv_virtualenv_hook() { local ret=$? if [ -n "$VIRTUAL_ENV" ]; then eval "$(pyenv sh-activate --quiet || pyenv sh-deactivate --quiet || true)" || true else eval "$(pyenv sh-activate --quiet || true)" || true fi return $ret }; typeset -g -a precmd_functions if [[ -z $precmd_functions[(r)_pyenv_virtualenv_hook] ]]; then precmd_functions=(_pyenv_virtualenv_hook $precmd_functions); fi”’'
What exactly am I doing wrong here?

A bash function that runs script

I'm trying to write a bash function named myrun, such that doing
myrun script.py
with a Python file:
#MYRUN:nohup python -u script.py &
import time
print 'Hello world'
time.sleep(2)
print 'Once again'
will run the script with the command specified in the first line of the file, just after #MYRUN:.
What should I insert in .bashrc to allow this? Here is what I have now:
myrun () {
[[ "$1" = "" ]] && echo "usage: myrun python_script.py" && return 0
<something with awk here or something else?>
}
A minimalist version:
$ function myrun {
[[ "$1" = "" ]] && echo "usage: myrun python_script.py" && return
local cmd=$(head -n 1 < "$1" | sed s'/# *MYRUN://')
$cmd
}
$ myrun script.py
appending output to nohup.out
$ cat nohup.out
Hello world
Once again
$
(It's not clear to me whether you're better off using eval "$cmd" or simply $cmd in the last line of the function, but if you want to include the "&" in the MYCMD directive, then $cmd is simpler.)
With some basic checking:
function myrun {
[[ "$1" = "" ]] && echo "usage: myrun python_script.py" && return
local cmd=$(head -n 1 <"$1")
if [[ $cmd =~ ^#MYRUN: ]] ; then cmd=${cmd#'#MYRUN:'}
else echo "myrun: #MYRUN: header not found" >&2 ; false; return ; fi
if [[ -z $cmd ]] ; then echo "myrun: no command specified" >&2 ; false; return; fi
$cmd # or eval "$cmd" if you prefer
}
This is unrelated to Bash. Unfortunately, the shebang line cannot portably contain more than a single argument or option group.
If your goal is to specify options to Python, the simplest thing is probably a simple sh wrapper:
#!/bin/sh
nohup python -u <<'____HERE' &
.... Your Python script here ...
____HERE

BASH - crontab is always running except the python script

When i run this script from shell /var/tmp/server_always_alive.sh manually has no problem works. But when i let it run with crontab it never running even all the logics are correct.
How can i make the python server.py run via this crontab?
sun#sun-Inspiron-One-2320:~$ uname -a
Linux sun-Inspiron-One-2320 3.5.0-17-generic #28-Ubuntu SMP Tue Oct 9 19:31:23 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
/var/tmp/server_always_alive.sh:
#!/bin/bash
echo "test 1"
echo "test 2"
# 58888 TCP port is server port of server.py, if its not running server.py has to execute auto
main=$(export DISPLAY=:0.0 && lsof -i tcp:58888 | grep LISTEN | awk '{print $2}')
if [ -z "$main" ]; then
export DISPLAY=:0.0 && python /var/tmp/python/server.py &
sleep 2
break
fi
echo "test 3"
echo "all runs except python server.py"
crontab :
* * * * * /var/tmp/server_always_alive.sh &
DISPLAY=:0.0 indicates your python 'server' is connecting to an X server. Why?
Cron won't have the necessary X "cookie". , and almost certainly won't be running as the same user as the X server.
edit: I'll take you at your word that you're running as the correct user.
edit: If you really need to run a graphical program from cron, try
xhost +si:localuser:`whoami`
For reference to alternative workout.
Step 1: Put python script on this following script= save it in /var/tmp/main.sh
A) NON GUI BASED
#!/bin/sh
script='/my/python/script/is/here/ok.py'
/usr/bin/python $script &
B) GUI (GTK/TK etc)
#!/bin/sh
script='/my/python/script/is/here/ok.py'
export DISPLAY=:0.0 && /usr/bin/python $script &
Step 2: now make a file in /etc/init.d/scriptname_what_ever_feed_i_name with following (copy paste)
#! /bin/sh
PATH=/bin:/usr/bin:/sbin:/usr/sbin
DAEMON=/home/CHANGE _ ____ HERE ______ to the Step 1 file name
PIDFILE=/var/run/scriptname.pid
test -x $DAEMON || exit 0
. /lib/lsb/init-functions
case "$1" in
start)
log_daemon_msg "Starting feedparser"
start_daemon -p $PIDFILE $DAEMON
log_end_msg $?
;;
stop)
log_daemon_msg "Stopping feedparser"
killproc -p $PIDFILE $DAEMON
PID=`ps x |grep feed | head -1 | awk '{print $1}'`
kill -9 $PID
log_end_msg $?
;;
force-reload|restart)
$0 stop
$0 start
;;
status)
status_of_proc -p $PIDFILE $DAEMON atd && exit 0 || exit $?
;;
*)
echo "Usage: /etc/init.d/atd {start|stop|restart|force-reload|status}"
exit 1
;;
esac
exit 0
Step 3: make it executeable chmod +x /etc/init.d/scriptname_what_ever_feed_i_name and chmod -R 777 /etc/init.d/scriptname_what_ever_feed_i_name so that as any user you can execute it without sudo.
Step 4: for example:
/etc/init.d/scriptname_what_ever_feed_i_name restart
or
* * * * * /etc/init.d/scriptname_what_ever_feed_i_name restart
WORKING - and much better/safer.
ps aux | grep python
root 5026 0.5 0.3 170464 19336 pts/0 S 07:40 0:00 /usr/bin/python /var/tmp/python/server.py
Now you can start and stop your python script using the command /etc/init.d/scriptname start or stop manually or cron etc

shell start / stop for python script

I have a simple python script i need to start and stop and i need to use a start.sh and stop.sh script to do it.
I have start.sh:
#!/bin/sh
script='/path/to/my/script.py'
echo 'starting $script with nohup'
nohup /usr/bin/python $script &
and stop.sh
#!/bin/sh
PID=$(ps aux | grep "/path/to/my/script.py" | awk '{print $2}')
echo "killing $PID"
kill -15 $PID
I'm mainly concerned with the stop.sh script. I think that's an appropriate way to find the pid but i wouldn't bet much on it. start.sh successfully starts it. when i run stop.sh, i can no longer find the process by "ps aux | grep 'myscript.py'" but the console outputs:
killing 25052
25058
./stop.sh: 5: kill: No such process
so it seems like it works AND gives an error of sorts with "No such process".
Is this actually an error? Am I approaching this in a sane way? Are there other things I should be paying attention to?
EDIT - I actually ended up with something like this:
start.sh
#!/bin/bash
ENVT=$1
COMPONENTS=$2
TARGETS=("/home/user/project/modules/script1.py" "/home/user/project/modules/script2.py")
for target in "${TARGETS[#]}"
do
PID=$(ps aux | grep -v grep | grep $target | awk '{print $2}')
echo $PID
if [[ -z "$PID" ]]
then
echo "starting $target with nohup for env't: $ENVT"
nohup python $target $ENVT $COMPONENTS &
fi
done
stop.sh
#!/bin/bash
ENVT=$1
TARGETS=("/home/user/project/modules/script1.py" "/home/user/project/modules/script2.py")
for target in "${TARGETS[#]}"
do
pkill -f $target
echo "killing process $target"
done
It is because ps aux |grep SOMETHING also finds the grep SOMETHING process, because SOMETHING matches. After the execution the grep is finished, so it cannot find it.
Add a line: ps aux | grep -v grep | grep YOURSCRIPT
Where -v means exclude. More in man grep.
The "correct" approach would probably be to have your script write its pid to a file in /var/run, and clear it out when you kill the script. If changing the script is not an option, have a look at start-stop-daemon.
If you want to continue with the grep-like approach, have a look at proctools. They're built in on most GNU/Linux machines and readily available on BSD including OS X:
pkill -f /path/to/my/script.py
init-type scripts are useful for this. This is very similar to one I use. You store the pid in a file, and when you want to check if it's running, look into the /proc filesystem.
#!/bin/bash
script_home=/path/to/my
script_name="$script_home/script.py"
pid_file="$script_home/script.pid"
# returns a boolean and optionally the pid
running() {
local status=false
if [[ -f $pid_file ]]; then
# check to see it corresponds to the running script
local pid=$(< "$pid_file")
local cmdline=/proc/$pid/cmdline
# you may need to adjust the regexp in the grep command
if [[ -f $cmdline ]] && grep -q "$script_name" $cmdline; then
status="true $pid"
fi
fi
echo $status
}
start() {
echo "starting $script_name"
nohup "$script_name" &
echo $! > "$pid_file"
}
stop() {
# `kill -0 pid` returns successfully if the pid is running, but does not
# actually kill it.
kill -0 $1 && kill $1
rm "$pid_file"
echo "stopped"
}
read running pid < <(running)
case $1 in
start)
if $running; then
echo "$script_name is already running with PID $pid"
else
start
fi
;;
stop)
stop $pid
;;
restart)
stop $pid
start
;;
status)
if $running; then
echo "$script_name is running with PID $pid"
else
echo "$script_name is not running"
fi
;;
*) echo "usage: $0 <start|stop|restart|status>"
exit
;;
esac
ps aux | grep "/path/to/my/script.py"
will return both the pid for the instance of script.py and also for this instance of grep. That'll probably be why you're getting a no such process: by the time you get around to killing the grep, it's already dead.
I don't have a unix box on at the moment, so i can't test this, but it should be fairly simple to get the idea.
start.sh:
if [ -e ./temp ]
then
pid=`cat temp`
echo "Process already exists; $pid"
else
script='/path/to/my/script.py'
echo 'starting $script with nohup'
nohup /usr/bin/python $script &
echo $! > temp
fi
stop.sh:
if [ -e ./temp ]
then
pid=`cat temp`
echo "killing $pid"
kill -15 $PID
rm temp
else
echo "Process not started"
fi
Try this out.

Categories