It's possible to feed input to multiple processes. When multiple processes are reading from the same pipe or terminal, each byte goes to one of the processes, whichever happens to read that particular byte first. When only one process is actively reading, it gets the input. When multiple processes are actively reading at the same time, which one gets the input is unpredictable.
You are running afoul of buffering. Most programs, evidently including A, read input a whole buffer at a time — typically a few hundred bytes or a few kilobytes — and then store it in their own memory until they get around to processing it. This is a lot faster than reading one byte at a time. But in this scenario, it means that A reads more than the part that it will process before calling B, so the input meant for B is already consumed by A when B starts.
If you can make B read from a different source, that's of course a solution.
If you have control over how A is executed, try stdbuf from GNU coreutils. It hooks into library calls to cause the process to read one byte at a time. This works with most programs, but not all: it doesn't work with statically linked executables and it doesn't work if the program uses a buffering method other than the standard library (stdio).
… | stdbuf -i 1 A
Alternatively, try reading from a regular file. When A has read input from a pipe or terminal, it can't put it back. But when it's read from a regular file, it can rewind the reading position before calling B. This is how the read shell builtin behaves, for example. There's no guarantee that the particular program A does it, in fact it isn't very common behavior, but if it does, that's a simple solution.
If that doesn't work, or if you have no control over how A is executed, you'll need to arrange the timing of the input so that the part intended for B is not present until B starts. How to do that depends on how you can detect that B has started. A possible solution, but a fragile one, is to put a delay:
{ echo 123; sleep 1; echo xyzzy; } | A
This only works if A calls B within 1 second, which is fragile. A more reliable solution is to detect output produced by A (or B). This is the kind of problem that expect is designed to solve. For example, if B displays some kind of prompt like B>:
#!/usr/bin/expect -f spawn A send "123\r" expect "B>" send "xyzzy\r"
Areading data? Because a simple test program written in bash shows no problem (sorry for the formatting; that's comments..):$ cat a #!/bin/bash read x echo In a: $x read, calling b ./b $ cat b #!/bin/bash read x echo In b: $x read $ echo -e '123\nxyzzy' | ./a In a: 123 read, calling b In b: xyzzy readscanfand B is/bin/sh.