1

I'm trying to pass a here string to a command that expects three values to be passed interactively. It seems like it should be simple enough, but for some reason, the program seems to only be receiving the first line of the here string properly and ignoring everything after the first \n.

Here is what I'm trying:

command <<< $'firstValue\nsecondValue\nthirdValue\n'

If anyone could tell me what I'm missing, I'd appreciate it greatly. I'm not sure if it's relevant or not, but the second value contains a space. I'm running this on a Mac.

Jared
  • 91
  • 1
  • 8
  • You’re doing it right. The problem might be in the `command` script/program. – vdavid Apr 28 '17 at 13:56
  • I didn't write the command, so unfortunately I can't change that. I have tested the command, and it works fine when I manually input the values. I was under the impression that command wouldn't be able to tell the difference between my here string and me putting the values in interactively. – Jared Apr 28 '17 at 13:59
  • Works ok for `cat <<< $'a b\nc d\ne f'`. – choroba Apr 28 '17 at 14:01
  • Would it make a difference that I have a \n after the third value? – Jared Apr 28 '17 at 14:07
  • Is the `command` reading from stdin or from `/dev/tty`? What kind of command is it (asking for credentials vs asking for data to process)? – Jens Apr 28 '17 at 14:08
  • I don't know how to test that, but the fact that it is successfully getting part of the here string suggests stdin I think. – Jared Apr 28 '17 at 14:12
  • Is your command supposed to read all the arguments at once, or is it supposed to read them one at a time? – l'L'l Apr 28 '17 at 14:13
  • It asks one at a time. – Jared Apr 28 '17 at 14:14
  • Does this work: `printf '%s\n' "first Value" "second Value" "third Value" | command`? – Jens Apr 28 '17 at 14:15
  • @Jens I tried this and got the same behaviour as before – Jared Apr 28 '17 at 14:26
  • Then we need to know what exactly `command` is. Looks like it has a hidden issue... – Jens Apr 28 '17 at 14:39
  • I'm thinking it may be a timing issue. With the yes command, I can enter more than one value, but if the value is long, it gets chopped up. The command I'm using is: cf uups -p 'key1,key2,key3' – Jared Apr 28 '17 at 15:09

2 Answers2

0

I would maybe recommend setting up a while read for your here arguments:

#!/bin/bash

read -r -d '' vals <<EOT
first value
second value
third value
EOT

command <<< "$vals"

If you wanted to run the command each time on each argument:

while read -r src; do command "$src" ; done<<<"$vals" 

Since you need the arguments run one at a time it might be easier to manage, and then you won't need to worry about the newline \n issues.

l'L'l
  • 44,951
  • 10
  • 95
  • 146
  • I'm pretty new to bash, but wouldn't this execute command 3 separate times, one with each value? – Jared Apr 28 '17 at 14:39
  • @Jared: Yes, I thought that was what you were wanting to do. – l'L'l Apr 28 '17 at 14:40
  • Oh, I'm sorry if I wasn't clear. I need to run this command, which will then ask me for a value 3 times, and I want to enter those values in order. – Jared Apr 28 '17 at 14:42
  • Ah, okay I understand now — no worries :) – l'L'l Apr 28 '17 at 14:45
  • I think I may have misunderstood here strings. I have tried with the yes command and I'm seeing better results. – Jared Apr 28 '17 at 14:45
  • @Jared: If you replace the entire last `while read` line with `command <<< "$vals"` does it have the behavior you want? – l'L'l Apr 28 '17 at 14:56
  • No, thanks for the suggestion, but it seems like it only ever takes the first line when I enter more than one thing. I'm wondering if it's a timing issue, because the yes command will successfully pass y 3 times, but if i try a longer string it gets chopped up and entered three times. – Jared Apr 28 '17 at 15:03
  • Yes, it very well sounds like a race condition, since all of those values are sent to the command essentially at once. So if the command needs to process the first line whatever follows is likely going to be missed. – l'L'l Apr 28 '17 at 15:27
  • Yes it seems it was a race condition. I got it by piping (printf 'value1\n'; sleep 2; printf 'value2\n'; sleep 2; printf 'value3\n') into the command. – Jared Apr 28 '17 at 15:35
0

It turns out that the command I was passing the here string to couldn't handle the input fast enough from the here string. I ended up using the following workaround:

(printf 'value1\n'; sleep 2; printf 'value2\n'; sleep 2; printf 'value3\n') | command
Jared
  • 91
  • 1
  • 8