`&` at the end of `cmd` doesn't run the command in background
Thanks for your bug report!
Before submitting this issue, please make sure the same problem was not already reported by someone else.
Please describe the bug you're facing. Consider pasting example
when using & at the end of a command doesn't make it a background task.
Taskfiles showing how to reproduce the problem.
run:
cmds:
- task: build
- echo "Running server..."
- ./{{.APP_NAME}} > out.txt &
- echo "Server running..."
- Task version: latest
- Operating System: macOS and Linux
ok so, I found the problem basically the task ends before the server can start may be we should add the support for disown in this
This appears to be an issue with mvdan/sh. See replication steps below:
service.sh:
#!/bin/bash
for i in {1..5}; do sleep 1s && echo "$i"; done
> bash -c "./service.sh > out.txt &":
Creates the file out.txt and appends the numbers 1..5 as a background process
> gosh -c "./service.sh > out.txt &":
Does nothing :/
I think the problem is that the parent task ends and it forces the child process created using & to end as well.
I don't think this is to do with Task. As I said, this problem also exists when executing your command directly with gosh (the interpreter used by Task).
Also, if we write a Taskfile like this:
version: '3'
tasks:
sleep-5s-bg:
cmds:
- sleep 5s &
ps:
cmds:
- ps
and then run
> task sleep-5s-bg
> task ps
task: [ps] ps
PID TTY TIME CMD
...
416575 pts/1 00:00:00 task
416583 pts/1 00:00:00 sleep
You can see that the task executes sleep in the background and exits, but if you check ps, the sleep process is still running (i.e. Task is not killing the process when it exits).
This appears to only be a problem with combining redirection (> somefile) with job control (&)
I was able to reproduce the issue without using redirection.
This task does not start dolphin by some reason.
dolphin:
cmds:
- 'dolphin . &'
The workaround is appending some dummy command to the main one.
dolphin:
cmds:
- 'dolphin . &'
- ':'
Ran into this starting up an express process in the background.
Adding something like sleep 10 after the & works, but it seems to be relative to the OS-level process setup time.
I also ran into this issue, but none of the workarounds seem to work consistently (adding a dummy : task, or adding a sleep 5).
I was just about to create my first task and stumbled across this problem. I have now actually invested 2 hours to find the error, as I never thought that it was due to the task file or the interpreter. Unfortunately, the workaround with : does not work for me. I just checked the docs, but could not find something like this: Is there an option to disable mvdan/sh and use /bin/bash or /bin/sh directly?
Would it be possible to defer a call to wait with the pid of the command? Trying to think of how you would get the pid to the wait command though.
I tried this, and I couldn't get the pid without using a sub-subshell (not sure why?), and since the defer tasks are run in a different subshell, it's not possible to wait for it.
version: 3
tasks:
default:
cmds:
- mkdir -p run
- for: [chicken, duck]
task: process-item
vars:
ITEM: '{{.ITEM}}'
process-item:
cmds:
- |
sh -c 'sleep 30 &
echo $! > run/{{.ITEM}}'
- echo {{.ITEM}}
- defer: bash -c "wait $(cat run/{{.ITEM}})"
Output:
$ task
task: [default] mkdir -p run
task: [process-item] sh -c 'sleep 30 &
echo $! > run/chicken'
task: [process-item] echo chicken
chicken
task: [process-item] bash -c "wait $(cat run/chicken)"
bash: wait: pid 83816 is not a child of this shell
task: [process-item] sh -c 'sleep 30 &
echo $! > run/duck'
task: [process-item] echo duck
duck
task: [process-item] bash -c "wait $(cat run/duck)"
bash: wait: pid 83820 is not a child of this shell
I couldn't get the pid without using a sub-subshell (not sure why?)
Okay, I discovered the reason we can't get the pid: mvdan/sh#221
This library is written in Go, so it can't spawn sub-processes.
It works if you run in bg both the subcommand in the subshell and the subshell itself, followed by sleep:
task test_bg
task: [test_bg] bash -c 'sleep 10 & echo "PID $!"'& sleep 1
[test_bg] PID 4213
ps -fp 4213
UID PID PPID TTY STIME COMMAND
cri 4213 1 cons1 12:33:17 /usr/bin/sleep
or, simpler, no PID output:
task test_bg
task: [test_bg] $(sleep 10&)& sleep 1
ps -ef| grep sleep
cri 4367 1 cons1 12:43:49 /usr/bin/sleep
Tested on both Windows and Linux.
See https://github.com/go-task/task/issues/162
what is the solution to spawn a disowned process ?
@leobenkel this worked for me:
start-ollama:
cmds:
- bash -c 'nohup ollama serve >/dev/null 2>&1 &'