0

Where does the command in the braces run? In current bash or the newly opening Telnet terminal?

{
sleep 2
echo "root"
sleep 2
echo "password"
} | telnet 192.168.1.11

If the command in the braces is run in current bash, then both the command before the pipe(|) and after the command are started at the same time? It's really out of my expectation.

I used to call commands like find . -type f | du -sh, I thought du is called when find has finishes its work.

Could somebody shed somelight on this matter?

John
  • 2,963
  • 11
  • 33
  • The commands are run in the current bash and their output sent to the pipe. – Diego Torres Milano Jun 08 '22 at 01:54
  • @DiegoTorresMilano Do you mean both `{ sleep 2 echo "root" }` and `telnet` are started **almost** at the same time other than `telnet` is started after the command in the braces finishes its work? – John Jun 08 '22 at 01:55
  • Yes, (almost) at the same time – Diego Torres Milano Jun 08 '22 at 01:57
  • Try something like `(date>/dev/tty; sleep 5) | (date>/dev/tty; sleep 5)` and you'll see the same date twice but the entire pipeline takes almost 5secs to run – Diego Torres Milano Jun 08 '22 at 01:59
  • Better take a look at [expect](https://linux.die.net/man/1/expect) – Diego Torres Milano Jun 08 '22 at 02:02
  • @DiegoTorresMilano Good example! For `find . -type f | du -sh`, both `find` and `du` are started at the same time, and the `stdin` of `du` is linked to the `stdout` of `stdout` of `find`, so `du` `waits` for the output of `find`. Am I right? – John Jun 08 '22 at 02:04
  • Basically yes. Here are some examples: https://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-4.html – Diego Torres Milano Jun 08 '22 at 02:10
  • @DiegoTorresMilano The link is very useful indeed. But it's a pity that it does not explicitly tell the readers the command after the pipe and before pipe are **started almost at the same time**. *And what's worse*, many readers like me are more likely thought that the commands called in sequence. – John Jun 08 '22 at 02:29
  • @John This is a fairly common misunderstanding, but I think it's also rather difficult to explain clearly (parallel processing is inherently a bit tricky to understand) and trying to explain it anytime we explain pipes would just cause more (different) confusion. BTW, there's a related (also common) mistake about redirecting output with `>`, which actually starts (and empties the file) *before* the command runs (see [this question](https://stackoverflow.com/questions/6696842/how-can-i-use-a-file-in-a-command-and-redirect-output-to-the-same-file-without-t)). – Gordon Davisson Jun 08 '22 at 03:31
  • Usually commands in `{ ... }` run in the current bash but this it not true for `{ ... } | ...`. eg. `{ pgrep bash | wc -l; }; ( pgrep bash | wc -l ); { pgrep bash | wc -l; } | cat` – jhnc Jun 08 '22 at 04:08
  • @jhnc What's `{ ... } | .... eg. { pgrep bash | wc -l; }; ( pgrep bash | wc -l ); { pgrep bash | wc -l; } | cat`? – John Jun 08 '22 at 04:50
  • `...` are [ellipses](https://en.wikipedia.org/wiki/Ellipsis). The examples illustrate that the number of shells running differs when braces are in a pipeline (in a pipeline, braces are equivalent to using parentheses) – jhnc Jun 08 '22 at 06:11
  • @jhnc Why they are different in `{ pgrep bash | wc -l; }; ( pgrep bash | wc -l ); { pgrep bash | wc -l; } | cat`? – John Jun 08 '22 at 06:13
  • 1
    Because [each command in a pipeline is executed in a subshell](https://www.gnu.org/software/bash/manual/html_node/Pipelines.html) – jhnc Jun 08 '22 at 06:17

0 Answers0