Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

& at the end of cmd doesn't run the command in background #928

Open
Mussabaheen opened this issue Nov 10, 2022 · 15 comments
Open

& at the end of cmd doesn't run the command in background #928

Mussabaheen opened this issue Nov 10, 2022 · 15 comments
Labels
dep: mvdan/sh Issues related to the upstream interpreter used by Task. type: bug Something not working as intended.

Comments

@Mussabaheen
Copy link

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
@github-actions github-actions bot added the state: needs triage Waiting to be triaged by a maintainer. label Nov 10, 2022
@Mussabaheen
Copy link
Author

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

@pd93
Copy link
Member

pd93 commented Nov 10, 2022

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 :/

@pd93 pd93 added type: bug Something not working as intended. dep: mvdan/sh Issues related to the upstream interpreter used by Task. and removed state: needs triage Waiting to be triaged by a maintainer. labels Nov 10, 2022
@Mussabaheen
Copy link
Author

I think the problem is that the parent task ends and it forces the child process created using & to end as well.

@pd93
Copy link
Member

pd93 commented Nov 11, 2022

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 (&)

@Chi-teck
Copy link

Chi-teck commented Jan 17, 2023

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 . &'
   -  ':'

@toddpi314
Copy link

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.

@pyrho
Copy link

pyrho commented Feb 22, 2023

I also ran into this issue, but none of the workarounds seem to work consistently (adding a dummy : task, or adding a sleep 5).

@matzeeable
Copy link

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?

@q0rban
Copy link
Contributor

q0rban commented Aug 9, 2023

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.

@q0rban
Copy link
Contributor

q0rban commented Aug 9, 2023

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

@q0rban
Copy link
Contributor

q0rban commented Aug 11, 2023

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.

@cr1cr1
Copy link

cr1cr1 commented Jan 2, 2024

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 #162

@leobenkel
Copy link

what is the solution to spawn a disowned process ?

@JonZeolla
Copy link
Contributor

@leobenkel this worked for me:

  start-ollama:
    cmds:
      - bash -c 'nohup ollama serve >/dev/null 2>&1 &'

@Andrew99xx
Copy link

I think this needs to be implemented as feature

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dep: mvdan/sh Issues related to the upstream interpreter used by Task. type: bug Something not working as intended.
Projects
None yet
Development

No branches or pull requests