Skip to content

interp: consider some support for PIDs #221

Closed

Description

@rhd

Hi, I was playing around with go-task and I couldn't get this to work: sleep 10 & echo $!. It would only print a new line but not the PID of the sleep call. @andreynering suggested I post an issue here.

Any suggestions?

Thanks!

Activity

  1. mvdan commented on Mar 13, 2018

    @mvdan
    Owner

    This library is written in Go, so it can't spawn sub-processes. If I make $! work, it will always print the same as $$. That's part of the reason why I've been hesitant to add it.

    I guess I could add it, but that behavior might confuse lots of people. I should add docs about these gotchas in the interpreter.

  2. rhd commented on Mar 14, 2018

    @rhd
    Author

    Yea, printing $$ is mostly useless. No way to use os/exec to spawn the process?

  3. mvdan commented on Mar 16, 2018

    @mvdan
    Owner

    How, exactly? os/exec executes programs. It does not allow forking alone, because it wouldn't work in Go. For example, see https://stackoverflow.com/questions/28370646/how-do-i-fork-a-go-process

    The only portable and stable way to have multiple processes would be for the interpreter to run from a shell, say gosh, and then spawning subshells via exec.Command("gosh", ...). But the point of the interpreter is being embeddable into a binary, so you'd lose that. You'd also lose other features like controlling the interpreter via modules and the context.

    There's also the question of why you'd need $$ and $! in the first place. If you want to write portable shell scripts, how can you safely use them for anything other than printing them?

    All in all, I decided not to do it by default because it's too much hassle for little gain. However, I'm open to doing the option above - depending on its own shell executable - via an option like #171.

    There's always the option of using virtual PIDs, to make it so that $$ and $! could be different among goroutines. But I presume that will open a can of worms.

  4. mvdan commented on Mar 23, 2018

    @mvdan
    Owner

    Ping, @rhd? Did you have an implementation idea in mind?

  5. mvdan commented on Apr 22, 2018

    @mvdan
    Owner

    Timed out after a month - still open to suggestions, but I see no clear way forward right now.

  6. changed the title [-]How to get PID?[/-] [+]interp: how to get PID?[/+] on Apr 22, 2018
  7. Ckarles commented on May 29, 2021

    @Ckarles

    There's also the question of why you'd need $$ and $! in the first place. If you want to write portable shell scripts, how can you safely use them for anything other than printing them?

    I'm not trying to reopen the issue, thought I can give you an answer regarding my current problem.

    I would like to parallel build multiple things, and if one of them fail, exit !=0.
    The only way I could think of as of now is to spawn subshells then wait, unfortunately wait is pretty basic, and if the return code of the subshell is needed (and it is in this case), wait has to be called with a the pid of the process which you want to return the pid from.

    Therefore, without any indicator to point wait to, no return code can be gathered from a subshell.

  8. mvdan commented on May 29, 2021

    @mvdan
    Owner

    Thanks @Ckarles, that's a valid point. I'll reopen the issue for now.

    One way we could possibly do this is by having "virtual" PIDs by default, where each PID just maps to one of the goroutines running an interpreter's subshell. Then, we could still have wait work for those.

    We'd have to try to avoid conflicts between those per-goroutine PIDs and the real host system's PIDs, though. Maybe by making them start at a really big number, like 64k?

  9. reopened this on May 29, 2021
  10. changed the title [-]interp: how to get PID?[/-] [+]interp: consider some support for PIDs[/+] on May 29, 2021
  11. jubr commented on Mar 5, 2025

    @jubr

    Running into this again today, any new insights?

  12. mvdan commented on Mar 29, 2025

    @mvdan
    Owner

    This is implemented as of master:

    $ bash -c '{ sleep 0.01; false; } & echo $!; wait $!; echo $?'
    167991
    1
    $ gosh -c '{ sleep 0.01; false; } & echo $!; wait $!; echo $?'
    g1
    1
    

    Note that I went for a "g" prefix to differentiate these virtual PIDs, representing a goroutine in memory, from the real PIDs representing processes on the host system.

  13. added a commit that references this issue on Mar 29, 2025
    d48750a
  14. 33 remaining items

  15. prologic commented on Oct 18, 2026

    @prologic

    Can we revisit this? I've run into this and am using your project as a shell in a custom linux os called GoNix and this behaviour is currently a bit of a bug for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      ⌂ 换网址