Shell Pipe a Here-Document


I'm somehow confused. The goal is to execute the code of ${CMD} between two cat. I'm currently stuck with this:

cat << CMDEOF | sed -E 's|[[:space:]]+| |g'
expect << EXPECT
set timeout -1
spawn openssl ocsp  -index  ./CA/Signing-CA/DB/Signing-CA.db \
  -VAfile  ./CA/Signing-CA.crt \
  -CA  ./CA/Signing-CA.crt \
  -CApath  ./CA/ \
  -rsigner ./CA/Signing-CA.crt \
  -rkey  ./CA/Signing-CA/Private/Signing-CA.key \
  -resp_key_id \
  -reqin  /dev/stdin \
  -respout /dev/stdout -text -out ./OCSP.log
expect -re ".*phrase.*:.*"
send -- "MyPassphrase\r"
expect eof

eval "cat | ${CMD} | cat"

But this throws an error, that the Here-Document is inconsistent.

Another idea would be to use simple echo instead of expect ... but unfortunately I wasn't able to figure it out

CMD="(echo 'MyPassphrase') | openssl ocsp -index [...]"
eval "cat | ${CMD} | cat"


Please see section PASS PHRASE ARGUMENTS in openssl(1) for alternative means of passing pass phrases to openssl. I don't think using expect is the correct (and maintainable) way to do this.

EDIT: Ignore me, openssl ocsp does not seem to support -passin...
Please see section PASS PHRASE ARGUMENTS in openssl(1) for alternative means of passing pass phrases to openssl. I don't think using expect is the correct (and maintainable) way to do this.

EDIT: Ignore me, openssl ocsp does not seem to support -passin...

Yeah, tried my luck with that already ... ;)

But I found the solution. In order to achive the goal, the following two lines need to be changed:

expect << EXPECT | cat
eval "cat | ${CMD}"
Still, I couldn't get the script to work. Somehow the data coming through /dev/stdin is not the same as coming through e.g. PHP://input. There is something additional like a new line or any additional characters, which I can not identify. So OpenSSL ocsp throws errors when I try to read the request:

openssl ocsp -reqin /tmp/OCSP-Request -text
Error reading OCSP request
34379249528:error:0D07209B:asn1 encoding routines:ASN1_get_object:too long:/usr/src/secure/lib/libcrypto/../../../crypto/openssl/crypto/asn1/asn1_lib.c:145:
34379249528:error:0D068066:asn1 encoding routines:ASN1_CHECK_TLEN:bad object header:/usr/src/secure/lib/libcrypto/../../../crypto/openssl/crypto/asn1/tasn_dec.c:1306:
34379249528:error:0D06C03A:asn1 encoding routines:ASN1_D2I_EX_PRIMITIVE:nested asn1 error:/usr/src/secure/lib/libcrypto/../../../crypto/openssl/crypto/asn1/tasn_dec.c:814:
34379249528:error:0D08303A:asn1 encoding routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 error:/usr/src/secure/lib/libcrypto/../../../crypto/openssl/crypto/asn1/tasn_dec.c:751:Field=parameter, Type=X509_ALGOR
34379249528:error:0D08303A:asn1 encoding routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 error:/usr/src/secure/lib/libcrypto/../../../crypto/openssl/crypto/asn1/tasn_dec.c:751:Field=hashAlgorithm, Type=OCSP_CERTID
34379249528:error:0D08303A:asn1 encoding routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 error:/usr/src/secure/lib/libcrypto/../../../crypto/openssl/crypto/asn1/tasn_dec.c:751:Field=reqCert, Type=OCSP_ONEREQ
34379249528:error:0D08303A:asn1 encoding routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 error:/usr/src/secure/lib/libcrypto/../../../crypto/openssl/crypto/asn1/tasn_dec.c:711:Field=requestList, Type=OCSP_REQINFO
34379249528:error:0D08303A:asn1 encoding routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 error:/usr/src/secure/lib/libcrypto/../../../crypto/openssl/crypto/asn1/tasn_dec.c:751:Field=tbsRequest, Type=OCSP_REQUEST
First before I explain the differences between:

and yes I can see you already partially know how to use these :)

variable="`echo something`" or,
variable="$(echo something)" or,
echo ${I_AM_JUST_A_VARIABLE_IN_CURLY_BRACES}, it appears this is what you tried initially which is just a reference to a variable, but does not execute the contents between the curly braces.

I would put your command in a function and then call the function by its name which would run your commands in between the pipes.

But here is some more explanation of stuff below.

When you want to encapsulate a command there are at least 2 ways to do it.

The first I consider more deprecated, but is sometime necessary when you are encapsulating a command inside of a already encapsulated command.

You can put it between 2 grave characters which is usually above you tab button it looks like `, not the ~.

A better way is to use $(echo blah).

Both of these methods require you to assign them to variables.

Neither of these 2 methods if assigned to a variable would allow the variable to execute as a command, you would need a function for that.

The way you had it was something=${blah} and then expecting "${something}" to function as a command.

An example with ${} would be I what to echo a statement with a variable in it that is concatenated like this:

encapsulatedCommand=$(echo "${Blah}World")
printf "$encapsulatedCommand"

--> HelloWorld

In the case above I only use ${} when I have text right next to the variable, otherwise you could leave off the curly braces.

So echo $encapsulatedCommand would return "HelloWorld"

If I did this:

encapsulatedCommand=$(echo "$BlahWorld")
printf "$encapsulatedCommand"

echo $encapsulatedCommand would return nothing
CMD="(echo 'MyPassphrase') | openssl ocsp -index [...]"
eval "cat | ${CMD} | cat"

The reason this does not work is because CMD="(echo 'MyPassphrase') produces no output to pipe into the next command