What's better, a fish or a bicycle? nohup
and exec
do different things.
exec
replaces the shell with another program. Using exec
in a simple background job isn't useful: exec myprogram; more stuff
replaces the shell with myprogram
and so doesn't run more stuff
, unlike myprogram; more stuff
which runs more stuff
when myprogram
terminates; but exec myprogram & more stuff
starts myprogram
in the background and then runs more stuff
, just like myprogram & more stuff
.
nohup
runs the specificed program with the SIGHUP signal ignored. When a terminal is closed, the kernel sends SIGHUP to the controlling process in that terminal (i.e. the shell). The shell in turn sends SIGHUP to all the jobs running in the background. Running a job with nohup
prevents it from being killed in this way if the terminal dies (which happens e.g. if you were logged in remotely and the connection drops, or if you close your terminal emulator).
nohup
also redirects the program's output to the file nohup.out
. This avoids the program dying because it isn't able to write to its output or error output. Note that nohup
doesn't redirect the input. To fully disconnect a program from the terminal where you launched it, use
nohup myprogram </dev/null >myprogram.log 2>&1 &
You seem to be mistaken in that abc.py
would not be a command. If you can execute it, then is, just one with a dot in the name. Execute in the sense that you can do ./abc.py
, so the execute bits must be set. If you have to do python abc.py
than you it is not a command (yet).
In general, to make a normal python file abc.py
executable you should make sure the first line reads:
#!/usr/bin/env python
(This assumes you have /usr/bin/env
as a program, and that will find the python
command, which might be in /usr/local/bin
. It also assumes that you want to run the default python
(which is normally a link to a particular python version like python2.7
), you could also use python3
if that is available as a command).
After that do
chmod +x abc.py
mv abc.py abc
And then you can run ./abc
. If the current directory is in your path, or if you move abc
to a directory in your path, you should be able to execute abc
from anywhere.¹
There are however disadvantages of renaming and moving the file:
- you can no longer to
from abc import SomeClass
, as the file is renamed
- If the file is under revision control it might no longer be
So instead, what I normally do, is make a new file /usr/local/bin/abc
that looks like:
#!/usr/bin/env python
from abc import main
main()
and have at the bottom of abc.py
:
def main():
doing the real stuff
if __name__ == '__main__':
main()
The directory of abc.py
needs to be in the PATH python searches for modules, but this way it doesn't have to be changed, and can be used by any program as an import, and started as python abc.py
.
¹ The mv
is necessary to get rid of the dot in the command name, but not really necessary, you can invoke ./abc.py
if you don't rename it.
Best Answer
They are not quite the same thing as you notice by observing that one of them is used as the
argv[0]
value. This doesn't have to be the same as the basename of the executable; many/most things ignore it and you can put whatever you want in there.The first one is the actual path to the executable, for which there is an obvious necessity. The second one is passed to the process ostensibly as the name used to invoke it, but, e.g.:
Will work fine, presuming
/bin/ls
is the correct path.Some applications do, however, make use of
argv[0]
. Usually these have one or more symlinks in$PATH
; this is common with compression utilities (sometimes they use shell wrappers instead). If you havexz
installed,stat $(which xzcat)
shows it's a link toxz
, andman xzcat
is the same asman xz
which explains "xzcat is equivalent to xz --decompress --stdout". The way xz can tell how it was invoked is by checkingargv[0]
, making these equivalent: