4

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)

schrodingerscatcuriosity
  • 12,087
  • 3
  • 29
  • 57
ctac_
  • 1,960
  • 1
  • 6
  • 14

1 Answers1

6

? 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'
Stéphane Chazelas
  • 522,931
  • 91
  • 1,010
  • 1,501
  • With the -e option, there is no need of heredoc and command substitution. – ctac_ Apr 06 '21 at 14:49
  • @ctac_, True. I had assumed the OP wanted to use a heredoc (for instance because it allows to specify arbitrary text without having to worry about quoting), but that was interpolation on my part. See edit. – Stéphane Chazelas Apr 06 '21 at 16:00