An extension to Gilbert's answer , providing additional paranoia:
eval "$( openssl req -new -newkey rsa:2048 -subj / -days 365 -nodes -x509 \ -keyout >(printf 'keyout=%q\n' "$(</dev/stdin)") \ -out >(printf 'out=%q\n' "$(</dev/stdin)") )"
(Note that this is not appropriate if your data contains NULs that bash cannot store in its own shell variable, in which case you will want to assign the contents to your variables in base64 -encoded form).
Unlike echo "keyout='$(cat)'" , printf 'keyout=%q\n' "$(cat)" ensures that even malicious content cannot be eval uated by shell like wildcard, command redirection or other content other than letter data.
To explain why this is necessary, take a simplified case:
write_to_two_files() { printf 'one\n' >"$1"; printf 'two\n' >"$2"; } write_to_two_files >(echo "one='$(cat)'") >(echo "two='$(cat)'")
... we get an output similar to (but without special order):
two='two' one='one'
... which, when eval ed, sets two variables:
$ eval "$(write_to_two_files >(echo "one='$(cat)'") >(echo "two='$(cat)'"))" $ declare -p one two declare -- one="one" declare -- two="two"
However, let's say that our program behaves differently:
## Demonstrate why eval'ing content created by echoing data is dangerous write_to_two_files() { printf "'%s'\n" '$(touch /tmp/i-pwned-your-box)' >"$1" echo "two" >"$2" } eval "$(write_to_two_files >(echo "one='$(cat)'") >(echo "two='$(cat)'"))" ls -l /tmp/i-pwned-your-box
Instead of simply assigning the result to a variable, we rated it as code.
If you are interested in ensuring that the two print operations are performed at different times (preventing them from mixing), it is useful to add an additional lock. This is due to a temporary file, but does not write your material to disk (avoiding it is the most compelling reason to prevent the temporary use of files):
lockfile=$(mktemp -t output.lck.XXXXXX) eval "$( openssl req -new -newkey rsa:2048 -subj / -days 365 -nodes -x509 \ -keyout >(in=$(cat); exec 99>"$lockfile" && flock -x 99 && printf 'keyout=%q\n' "$in") \ -out >(in=$(cat); exec 99>"$lockfile" && flock -x 99 && printf 'out=%q\n' "$in") )"
Please note that we only block writing, not reading, so we canβt get into the conditions of the race (i.e. where openssl does not finish writing to file-A, since it is blocked when writing to file-B, which can never terminate because the subshell on the read side of file-A records contains a lock).