(You most likely have firstline set already when you tested that code in bash, its value should be empty at the end).
When running the pipeline
cat myfile | { read firstline; read secondline; }
the right hand side is running in a subshell. Not because of the { ...; } but because it's part of a pipeline. The subshell environment will contain the two variables firstline and secondline (after both have been read), but will be destroyed when the subshell terminates, discarding both variables.
This holds true for both POSIX sh and bash.
In bash (4.2+), you can work around this by setting the lastpipe shell option. From the bash manual:
Each command in a pipeline is executed as a separate process (i.e., in
a subshell). See COMMAND EXECUTION ENVIRONMENT for a description of a
subshell environment. If the lastpipe option is enabled using the
shopt builtin (see the description of shopt below), the last element of
a pipeline may be run by the shell process.
This would work in a script, but not in an interactive shell with job control enabled (it's the job control that makes it not work, not the interactivity).
Example:
$ cat script.sh
cat << EOF > myfile
line1
line2
EOF
cat myfile | { read firstline; read secondline; }
printf 'first=%s\n' "$firstline"
printf 'second=%s\n' "$secondline"
shopt -s lastpipe
cat myfile | { read firstline; read secondline; }
printf 'first=%s\n' "$firstline"
printf 'second=%s\n' "$secondline"
$ bash script.sh
first=
second=
first=line1
second=line2
In your particular case, you could also, in both POSIX sh and bash, do away with cat and the pipe completely and instead redirect into the compound command with the two read calls directly:
{ read firstline; read secondline; } <myfile
On a tangential note, you most likely do not have a real historical Bourne shell on your machine (unless it's a Solaris system before Solaris 11). I'm assuming you mean a modern POSIX sh shell.
$firstlineshould be empty inbashas well at the end. Did you setfirstlinebefore running this code? Unset it withunset firstlineand try again. – Kusalananda May 11 '20 at 18:36{...}in bash, unless you have theshopt -s lastpipeset. Posix shells also do not print that value. – May 11 '20 at 22:39