Pass text to program expecting a file
Related to a question I asked on Stack Overflow: Passing multiple lines of code to wsadmin.sh?.
I have, as a string, a few lines of input that I need to feed into a command. The command, however, only accepts a file full of input.
Is there some way I could store the lines in a temporary file or pipe which never actually gets written to disk and then feed that directly into the program?
How do I go about acquiring the pipe, feeding the input into it, passing that pipe to the command, and then getting rid of the pipe?
Solution 1:
Another solution is to use Process Substitution in Bash. If your system has named pipes, you can use this feature.
It is used like this:
program_expecting_a_file <(list)
where list
is a sequence of shell commands (actually pipelines; the full details are here). list
will be executed, and its output will be connected to the pipe. The name of the pipe is then passed to your program.
NOTE: spaces are not allowed between <
and (
.
(The other substitution >(list)
also works as you'd expect.)
In your specific case, you could use
program_expecting_a_file <(echo "$your_strings")
although you may find @meuh's solution to be more elegant.
Update: A great many usage examples are to be found over at the Advanced Bash Scripting Guide.
Solution 2:
You can use a bash here-doc. For example,
$ cat -n <<<'a
> b'
1 a
2 b
If you have something in a bash variable you can also interpolate it: eg <<<"path is $PATH"
.
If your command insists on a filename you can give it /dev/stdin
. Eg:
$ sed -f /dev/stdin <<<'s/a/b/'
produces the output: s/b/b/
.
Solution 3:
Depending on what is in the script, you may be able to use the special filename - (minus) which stands for stdin
$ mycmd -
Line 1
Line 2
^D
Another method which may work for you is to open the file /dev/fd/0
which again stands for stdin.
A third option may be to create a FIFO (First In First Out). That is like a file, but it has two ends to it - you write to one end and read from the other.
-- Process 1 -- -- Process 2 --
$ mkfifo foo
$ cat foo
<waits> $ echo hello > foo
hello $
$ rm foo
Solution 4:
There's another option similar to the mycmd -
solution, but even for programs which don't handle -
specifically:
$ mycmd /dev/stdin
Line 1
Line 2
^D
/dev/stdin
seems to be OS-related and it works for me on Debian GNU/Linux, but I'm not sure where else it will work, too.