It depends on the application's capabilities. It may or may not insist on a named file, and it may or may not insist on a seekable file.
Some applications just read input from anywhere. Typically they default to reading from standard input. If you have the data in a string and you want to pass it to the application's standard input, there are a few ways. You can pass the information via a pipe:
printf '%s' "$the_recipe" | cook # passes $the_recipe exactly
printf '%s\n' "$the_recipe" | cook # passes $the_recipe plus a final newline
echo here because depending on the shell, it might mangle backslashes.
If the application insists on a file argument, it might accept
- to mean standard input. This is a common convention, but not systematic.
printf '%s\n' "$the_recipe" | cook -
If the application needs an actual file name, pass
/dev/stdin to mean standard input.
printf '%s\n' "$the_recipe" | cook /dev/stdin
For some applications, even this is not enough: they need a file name with certain properties, for example with a given extension, or they need a file name in a writable directory where they create temporary files. In such cases, you generally need a temporary file, although sometimes a named pipe is enough.
It's possible to give a pipe a name. I mention this for completeness, but it's rarely the most convenient way. It does avoid getting the data on disk. It's suitable if the application needs a file with constraints on the name, but doesn't need the file to be seekable.
printf '%s\n' "$the_recipe" >named.pipe & writer=$!
(Error checking omitted.)
If the application needs a seekable file, you need to create a temporary file. A seekable file is one where the application can go back and forth, reading arbitrary portions at a time. A pipe doesn't allow this: it needs to be read from start to finish, in sequence, without ever going backwards.
Bash, ksh and zsh have a convenient syntax to pass a string as input via a temporary file. Note that they always append a newline to the string (even if there's already one).
With other shells, or if you want to control which directory contains the temporary file, you need to create the temporary file manually. Most unices provide a
mktemp utility to create the temporary file securely. (Never use something like
! It allows other programs, even running as other users, to hijack the file.) Here's a script that creates a temporary file and takes care of removing it if interrupted.
trap 'rm -f "$tmp"' EXIT
trap 'rm -f "$tmp"; trap "" HUP; kill -INT $$' HUP
trap 'rm -f "$tmp"; trap "" INT; kill -INT $$' INT
trap 'rm -f "$tmp"; trap "" TERM; kill -INT $$' TERM
printf '%s\n' "$the_recipe" >"$tmp"
To choose where to create the temporary file, set the
TMPDIR environment variable for the
mktemp call. For example, to create the temporary file in the current directory rather than the default location for temporary files:
$PWD rather than
. gives you an absolute file name, which means you can safely call
cd in your script without worrying that
$tmp will no longer designate the same file.)
If the application needs a file name with a certain extension, you need to create a temporary directory and create a file there. To create the temporary directory, use
mktemp -d. Again, set the
TMPDIR environment variable if you want to control where the temporary directory is created.
trap 'rm -rf "$tmp"' EXIT
trap 'rm -rf "$tmp"; trap "" HUP; kill -INT $$' HUP
trap 'rm -rf "$tmp"; trap "" INT; kill -INT $$' INT
trap 'rm -rf "$tmp"; trap "" TERM; kill -INT $$' TERM
printf '%s\n' "$the_recipe" >"$tmp/myfile.ext"