I am trying to create a function that can run an arbitrary command, interact with the child process (specifics omitted), and then wait for it to exit. If successful, typing `run <command>` will appear to behave just like a bare `<command>`. 

If I weren't interacting with the child process I would simply write:

```
run() {
    "$@"
}

```

But because I need to interact with it while it runs, I have this more complicated setup with `coproc` and `wait`.

```
run() {
    exec {in}<&0 {out}>&1 {err}>&2
    { coproc "$@" 0<&$in 1>&$out 2>&$err; } 2>/dev/null
    exec {in}<&- {out}>&- {err}>&-

    # while child running:
    #     status/signal/exchange data with child process

    wait
}

```

(This is a simplification. While the `coproc` and all the redirections aren't really doing anything useful here that `"$@" &` couldn't do, I need them all in my real program.)

The `"$@"` command could be anything. The function I have works with `run ls` and `run make` and the like, but it fails when I do `run vim`. It fails, I presume, because Vim detects that it is a background process and doesn't have terminal access, so instead of popping up an edit window it suspends itself. I want to fix it so Vim behaves normally.

**How can I make `coproc "$@"` run in the "foreground" and the parent shell become the "background"?** The "interact with child" part neither reads from nor writes to the terminal, so I don't need it to run in the foreground. I'm happy to hand over control of the tty to the coprocess.

It is important for what I'm doing that `run()` be in the parent process and `"$@"` be in its child. I can't swap those roles. But I *can* swap the foreground and background. (I just don't know how to.)

Note that I am not looking for a Vim-specific solution. And I would prefer to avoid pseudo-ttys. My ideal solution would work equally well when stdin and stdout are connected to a tty, to pipes, or are redirected from files:

```
run echo foo                               # should print "foo"
echo foo | run sed 's/foo/bar/' | cat      # should print "bar"
run vim                                    # should open vim normally

```

---

> 
> Why using coprocesses?
> 
> 
> 

I could have written the question without coproc, with just

```
run() { "$@" & wait; }

```

I get the same behavior with just `&`. But in my use case I am using the FIFO coproc sets up and I thought it best not to oversimplify the question in case there's a difference between `cmd &` and `coproc cmd`.

> 
> Why avoiding ptys?
> 
> 
> 

`run()` could be used in an automated context. If it's used in a pipeline or with redirections then there wouldn't be any terminal to emulate; setting up a pty would be a mistake.

> 
> Why not using expect?
> 
> 
> 

I'm not trying to automate vim, send it any input or anything like that.