What does &| mean in shell? - linux

Put &| on the end of a command seems to detach the process from the shell. But where does it come from? and what's the right way to use it?

& will cause the process to be detached from the parent process (which in this case is the shell), but won't be disowned from it, which means when you'll close the shell, the process you started will be closed as well.
For disown it completely from the shell you need to do: my_process & and then disown %1
UPDATE
According to the information that the command &| ran on zsh the &| means:
&| - backgrounds the final command of the pipeline.

disown [ job ... ]
job ... &|
job ... &!
Remove the specified jobs from the job table; the shell will no longer report their status, and will not complain if you try to exit an interactive shell with them running or stopped. If no job is specified, disown the current job.
http://linux.die.net/man/1/zshbuiltins
Exit zsh, but leave running jobs open?

& will run the process in background. It will not occupy the terminal no more and wait it until finish.

Related

Disable background process termination notification

Is there a way to disable console notifications about background processes having terminated? Typically, something like this is printed when I run a completely unrelated command:
[1]+ Done some-command
I find it quite distracting.
If you don't care for your child processes exit codes then you can run them with setsid <cmd> or nohup <cmd> instead of <cmd>&. This will run them separately instead of in the background of the current console.
Using disown to remove the job from the current shell:
some-command & disown
More about disown -> https://askubuntu.com/a/612106/191003

Detaching a background process in zsh so that I can close the terminal

I have a terminal process running zsh in the Cygwin environment. I want to start a background process and then close the terminal process and have the background process running. However, when I exit the terminal, I get the error message that it can't exit, because a background process is still running. Example:
sleep 300 &
exit
I get the message zsh: you have running jobs.
The same with
nohup sleep 300 &
From the man page of zsh, I see that there is a command called disown which, from the description, might do what I want, but I don't know how to use it. According to the man page, it expects an argument job, but doesn't say what this argument actually is. I tried
sleep 300 &
disown $!
but get the message disown: job not found: 3964, so a job is obviously not a PID.
How can I do this correctly?
You need to refer to the job by it's job number
sleep 3000
control-z
bg
jobs
disown %3 (or whatever job number)
Hope this still helps at lest other readers: disown without any parameter disconnects the job with job number %1.
In addition you might want to check out the AUTO_CONTINUE on Ctrl-Z function.
alias bg='bg && disown'
in .zshrc to get bash-style behavior exiting terminal that launched process with keystrokes: Ctrl + Z, bg, exit

bash subshell vs vanilla command execution

As far as I know, when you run a command, like
> sleep 3
The shell process will fork another process and run the command with the child process.
However when you do
> (sleep 3)
you launch a subshell and execute the command. Essentially what it does is also fork another process to execute the command and wait the command to complete.
In this case, the behavior of the two commands looks the same, the parent shell will wait the sleep command to complete.
However sometime I noticed things are different with subshell:
For example, if I run some command like:
> virtualbox &
If I accidentally close the terminal the virtualbox will close at the same time. I already screwed my ongoing work several time in this way.
However if I do it this way it the program won't be killed even if I exited the terminal:
> (virtualbox &)
So I am not sure what's going on under the hood? How are the tasks started and managed by the shell with the two different approach?
As others write, using nohup will allow you to run the process without it being terminated when your shell is terminated. What happens in the two cases you describe is the following.
In the virtualbox & case virtualbox becomes a child of your shell. When your controlling terminal is closed all processes associated with it receive a SIGHUP signal, and are terminated.
In the (virtualbox &) case the command is executed within a subshell. When the subshell terminates, the command is disassociated from the shell and the terminal. (You can see this by running ps.) In this case the SIGHUP will not be sent to virtualbox, and therefore your command will not be terminated when the controlling terminal is closed.
The nohup command achieves the same result by specifying that the SIGHUP signal must be ignored.

Why is my bash script that executes another script not exiting?

I'm calling another script from my bash script like so -- with an ampersand.
OtherScriptThatDoesNotExit &
echo "done"
I see it getting to "done" but I still see my original script running is ps. Any idea why this could be? (Note, I'm running on Puppy Linux)
The script is still waiting on the subprocess you spawned. Use nohup, disown or screen to leave a long running task in the background and get back to your shell.

Asynchronous shell commands

I'm trying to use a shell script to start a command. I don't care if/when/how/why it finishes. I want the process to start and run, but I want to be able to get back to my shell immediately...
You can just run the script in the background:
$ myscript &
Note that this is different from putting the & inside your script, which probably won't do what you want.
Everyone just forgot disown. So here is a summary:
& puts the job in the background.
Makes it block on attempting to read input, and
Makes the shell not wait for its completion.
disown removes the process from the shell's job control, but it still leaves it connected to the terminal.
One of the results is that the shell won't send it a SIGHUP(If the shell receives a SIGHUP, it also sends a SIGHUP to the process, which normally causes the process to terminate).
And obviously, it can only be applied to background jobs(because you cannot enter it when a foreground job is running).
nohup disconnects the process from the terminal, redirects its output to nohup.out and shields it from SIGHUP.
The process won't receive any sent SIGHUP.
Its completely independent from job control and could in principle be used also for foreground jobs(although that's not very useful).
Usually used with &(as a background job).
nohup cmd
doesn't hangup when you close the terminal. output by default goes to nohup.out
You can combine this with backgrounding,
nohup cmd &
and get rid of the output,
nohup cmd > /dev/null 2>&1 &
you can also disown a command. type cmd, Ctrl-Z, bg, disown
Alternatively, after you got the program running, you can hit Ctrl-Z which stops your program and then type
bg
which puts your last stopped program in the background. (Useful if your started something without '&' and still want it in the backgroung without restarting it)
screen -m -d $command$ starts the command in a detached session. You can use screen -r to attach to the started session. It is a wonderful tool, extremely useful also for remote sessions. Read more at man screen.

Resources