Shell – Using dc with Standard Input or Heredoc

dchere-documentshell

dc can read command from a file or/and from standard input.
If I want to print user input :

cat essai_dc
[enter a number : ]
n
?
p

dc essai_dc 
  enter a number : 4
  4

Now, if I try with a heredoc :

dc <<EOF
> [enter a number : ]
> n
> ?
> p
> EOF  

enter a number : dc: stack empty

I get the same with standard input :

cat essai_dc | dc
enter a number : dc: stack empty

The command ? get the p and execute it but the stack is empty.
Is it possible to get it to work (tell dc to wait for the input)

Best Answer

? gets its input from standard input which is the here document here. You'd need to feed the script to dc using a different file descriptor. On systems with /dev/fd/n, that could be with:

dc /dev/fd/3 3<< 'EOF'
[enter a number : ]
n
?
p
EOF

Or you can use ksh-style process substitution (which generally uses /dev/fd/n underneath):

dc <(cat << 'EOF'
[enter a number : ]
n
?
p
EOF
)

Or doing away with the here-document and the call to the (generally) external cat utility:

dc <(printf %s \
'[enter a number : ]
n
?
p
'
)

Some dc implementations like GNU dc allow passing the contents of the dc script as argument with -e, so you could use command substitution:

dc -e "$(cat << 'EOF'
[enter a number : ]
n
?
p
EOF
)"

Or directly:

dc -e '[enter a number : ]
n
?
p'
Related Question