41

I have an executable that is used in a way such as the following:

executable -v -i inputFile.txt -o outputFile.eps 

In order to be more efficient, I want to use a Bash variable in place of the input file. So, I want to do something like the following:

executable -v -i ["${inputData}"] -o outputFile.eps 

Here, the square brackets represent some clever code.

Do you know of some trick that would allow me to pipe information into the described executable in this way?

Many thanks for your assistance

3
  • It's a bit unclear just what you want to happen. Like, what is value of inputData? Commented Feb 12, 2013 at 19:55
  • 1
    "${inputData}" is simple, ASCII data which I want to 'package' as a file without actually using a file (which may need to be stored in non volatile memory). The user mikyra suggests an approach involving process substitution which I think is exactly I need. Thanks for your help. Commented Feb 13, 2013 at 21:13
  • Ah, now I got it... Cool, I didn't know of that. Apparently it is a bash feature, not supported by plain sh or dash, so better remember to use #!/bin/bash when using that in a script. +1+1 Commented Feb 13, 2013 at 21:21

4 Answers 4

69

You can use the following construct:

<(command) 

So, to have bash create a FIFO with the command as the output for you, instead of your attempted -i ["${inputData}"], you would do:

-i <(echo "$inputData") 

Therefore, here is your final total command:

executable -v -i <(echo "$inputData") -o outputFile.eps 
Sign up to request clarification or add additional context in comments.

5 Comments

This process substitution is exactly what I need. Thank you very much for your assistance!
I encountered some command that need to seek the input file, where fifo pipe doesn't work. Zsh has a =() implemented as a temp file, which works well.
This fails if inputData contains literal backslashes, or is -e
For a solution that works in the cases that @Eric mentions, see here.
21

Echo is not safe to use for arbitrary input.

To correctly handle pathological cases like inputdata='\ntest' or inputdata='-e', you need

executable -v -i <(cat <<< "$inputData") 

In zsh, the cat is not necessary


Edit: even this adds a trailing newline. To output the exact variable contents byte-by-byte, you need

executable -v -i <(printf "%s" "$inputData") 

Comments

3

Note: zsh only:

To get a filename containing the contents of ${variable}, use:

<(<<<${variable}) 

Note:

  • <<<${variable} redirects STDIN to come from ${variable}
  • <<<${variable} is equivalent to (but faster than) cat <<<${variable}

So for the OP's case:

executable -v -i <(<<<${inputData}) -o outputFile.eps 

1 Comment

This also emits a trailing newline after the contents of variable, which in most cases doesn't matter, but might be worth drawing attention to
1

I couldn't find a better solution than making temporary file and reference it into a variable. For example:

key=$(mktemp); # Creating a random file in the tmp folder echo "some data" > $key; # Filling the file with content ssh -i $key user@localhost 

I assume when the bash session is close, the variable and temporary file is cleared

1 Comment

Actually, mktemp is an external utility, so it's up to your program to clean up the file when it's done with it

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.