How to pass a string to a command that expects a file? [duplicate]2019 Community Moderator ElectionUsing data read from a pipe instead than from a file in command optionsHow portable are /dev/stdin, /dev/stdout and /dev/stderr?Making multiple calls to a program via a bash shell scriptUsing process substitution to trick programs expecting files, with specific extensions as argument?How can the standard input of one program be passed as an arg to another?How to pass a string that specifies columns to be printed to awk?How to implement deferred stdout in child process without using temporary files?Timeout command breaks command that expects inputhow to pass command line argument to a filepass protocols to command from fileWhat is the correct way to assign a function containing chained commands to an alias in .bashrc?how to pass string variable as globbing argument to command

If I can solve Sudoku, can I solve the Travelling Salesman Problem (TSP)? If so, how?

Math equation in non italic font

Are ETF trackers fundamentally better than individual stocks?

Do the common programs (for example: "ls", "cat") in Linux and BSD come from the same source code?

The meaning of 振り in 無茶振り

Official degrees of earth’s rotation per day

Does .bashrc contain syntax errors?

What exactly is this small puffer fish doing and how did it manage to accomplish such a feat?

Is there a hypothetical scenario that would make Earth uninhabitable for humans, but not for (the majority of) other animals?

Are Roman Catholic priests ever addressed as pastor

Aluminum electrolytic or ceramic capacitors for linear regulator input and output?

World War I as a war of liberals against authoritarians?

Do I need to be arrogant to get ahead?

Book: Young man exiled to a penal colony, helps to lead revolution

What options are left, if Britain cannot decide?

Why is a white electrical wire connected to 2 black wires?

What's the meaning of a knight fighting a snail in medieval book illustrations?

What did “the good wine” (τὸν καλὸν οἶνον) mean in John 2:10?

Is it normal that my co-workers at a fitness company criticize my food choices?

How difficult is it to simply disable/disengage the MCAS on Boeing 737 Max 8 & 9 Aircraft?

What is the adequate fee for a reveal operation?

Violin - Can double stops be played when the strings are not next to each other?

Is a party consisting of only a bard, a cleric, and a warlock functional long-term?

Is there a symmetric-key algorithm which we can use for creating a signature?



How to pass a string to a command that expects a file? [duplicate]



2019 Community Moderator ElectionUsing data read from a pipe instead than from a file in command optionsHow portable are /dev/stdin, /dev/stdout and /dev/stderr?Making multiple calls to a program via a bash shell scriptUsing process substitution to trick programs expecting files, with specific extensions as argument?How can the standard input of one program be passed as an arg to another?How to pass a string that specifies columns to be printed to awk?How to implement deferred stdout in child process without using temporary files?Timeout command breaks command that expects inputhow to pass command line argument to a filepass protocols to command from fileWhat is the correct way to assign a function containing chained commands to an alias in .bashrc?how to pass string variable as globbing argument to command










29
















This question already has an answer here:



  • Using data read from a pipe instead than from a file in command options

    5 answers



Suppose a program cook takes one argument: the pathname of a text file containing the recipe of the food to cook. Suppose I wish to call this program from within a bash script, also suppose I already have the recipe in a string variable:



#!/bin/bash

the_recipe="$(cat << EOF
wash cucumbers
wash knife
slice cucumbers
EOF
)"

cook ... # What should I do here? It expects a file, but I only have a string.


How can I pass the recipe to the command when it expects a filename argument?



I thought about creating a temporary file just for the purpose passing a file, but I wish to know if there are alternative ways to solve this problem.










share|improve this question















marked as duplicate by Kusalananda bash
Users with the  bash badge can single-handedly close bash questions as duplicates and reopen them as needed.

StackExchange.ready(function()
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();

);
);
);
Mar 13 at 14:10


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.


















  • Similar: Using data read from a pipe instead than from a file in command options

    – ilkkachu
    Mar 13 at 12:15











  • The duplicate question talks about data arriving on a pipe. This question talks about having data in a variable. The code in this question may trivially be reformulated by adding printf '%sn' "$the_recipe" | cook, and this would make it an exact duplicate. I chose to mark this as a dupe of the other as it was older and as the other was more generally formulated from the start.

    – Kusalananda
    Mar 13 at 14:15
















29
















This question already has an answer here:



  • Using data read from a pipe instead than from a file in command options

    5 answers



Suppose a program cook takes one argument: the pathname of a text file containing the recipe of the food to cook. Suppose I wish to call this program from within a bash script, also suppose I already have the recipe in a string variable:



#!/bin/bash

the_recipe="$(cat << EOF
wash cucumbers
wash knife
slice cucumbers
EOF
)"

cook ... # What should I do here? It expects a file, but I only have a string.


How can I pass the recipe to the command when it expects a filename argument?



I thought about creating a temporary file just for the purpose passing a file, but I wish to know if there are alternative ways to solve this problem.










share|improve this question















marked as duplicate by Kusalananda bash
Users with the  bash badge can single-handedly close bash questions as duplicates and reopen them as needed.

StackExchange.ready(function()
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();

);
);
);
Mar 13 at 14:10


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.


















  • Similar: Using data read from a pipe instead than from a file in command options

    – ilkkachu
    Mar 13 at 12:15











  • The duplicate question talks about data arriving on a pipe. This question talks about having data in a variable. The code in this question may trivially be reformulated by adding printf '%sn' "$the_recipe" | cook, and this would make it an exact duplicate. I chose to mark this as a dupe of the other as it was older and as the other was more generally formulated from the start.

    – Kusalananda
    Mar 13 at 14:15














29












29








29


4







This question already has an answer here:



  • Using data read from a pipe instead than from a file in command options

    5 answers



Suppose a program cook takes one argument: the pathname of a text file containing the recipe of the food to cook. Suppose I wish to call this program from within a bash script, also suppose I already have the recipe in a string variable:



#!/bin/bash

the_recipe="$(cat << EOF
wash cucumbers
wash knife
slice cucumbers
EOF
)"

cook ... # What should I do here? It expects a file, but I only have a string.


How can I pass the recipe to the command when it expects a filename argument?



I thought about creating a temporary file just for the purpose passing a file, but I wish to know if there are alternative ways to solve this problem.










share|improve this question

















This question already has an answer here:



  • Using data read from a pipe instead than from a file in command options

    5 answers



Suppose a program cook takes one argument: the pathname of a text file containing the recipe of the food to cook. Suppose I wish to call this program from within a bash script, also suppose I already have the recipe in a string variable:



#!/bin/bash

the_recipe="$(cat << EOF
wash cucumbers
wash knife
slice cucumbers
EOF
)"

cook ... # What should I do here? It expects a file, but I only have a string.


How can I pass the recipe to the command when it expects a filename argument?



I thought about creating a temporary file just for the purpose passing a file, but I wish to know if there are alternative ways to solve this problem.





This question already has an answer here:



  • Using data read from a pipe instead than from a file in command options

    5 answers







bash shell-script






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 12 at 10:27









Kusalananda

135k17256424




135k17256424










asked Mar 12 at 9:58









FluxFlux

385213




385213




marked as duplicate by Kusalananda bash
Users with the  bash badge can single-handedly close bash questions as duplicates and reopen them as needed.

StackExchange.ready(function()
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();

);
);
);
Mar 13 at 14:10


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.









marked as duplicate by Kusalananda bash
Users with the  bash badge can single-handedly close bash questions as duplicates and reopen them as needed.

StackExchange.ready(function()
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();

);
);
);
Mar 13 at 14:10


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.














  • Similar: Using data read from a pipe instead than from a file in command options

    – ilkkachu
    Mar 13 at 12:15











  • The duplicate question talks about data arriving on a pipe. This question talks about having data in a variable. The code in this question may trivially be reformulated by adding printf '%sn' "$the_recipe" | cook, and this would make it an exact duplicate. I chose to mark this as a dupe of the other as it was older and as the other was more generally formulated from the start.

    – Kusalananda
    Mar 13 at 14:15


















  • Similar: Using data read from a pipe instead than from a file in command options

    – ilkkachu
    Mar 13 at 12:15











  • The duplicate question talks about data arriving on a pipe. This question talks about having data in a variable. The code in this question may trivially be reformulated by adding printf '%sn' "$the_recipe" | cook, and this would make it an exact duplicate. I chose to mark this as a dupe of the other as it was older and as the other was more generally formulated from the start.

    – Kusalananda
    Mar 13 at 14:15

















Similar: Using data read from a pipe instead than from a file in command options

– ilkkachu
Mar 13 at 12:15





Similar: Using data read from a pipe instead than from a file in command options

– ilkkachu
Mar 13 at 12:15













The duplicate question talks about data arriving on a pipe. This question talks about having data in a variable. The code in this question may trivially be reformulated by adding printf '%sn' "$the_recipe" | cook, and this would make it an exact duplicate. I chose to mark this as a dupe of the other as it was older and as the other was more generally formulated from the start.

– Kusalananda
Mar 13 at 14:15






The duplicate question talks about data arriving on a pipe. This question talks about having data in a variable. The code in this question may trivially be reformulated by adding printf '%sn' "$the_recipe" | cook, and this would make it an exact duplicate. I chose to mark this as a dupe of the other as it was older and as the other was more generally formulated from the start.

– Kusalananda
Mar 13 at 14:15











4 Answers
4






active

oldest

votes


















40














You can use the "fake" filename /dev/stdin which represents the standard input.



So execute this:



echo "$the_recipe" | cook /dev/stdin


The echo command and the pipe sends the contents of the specified variable to the standard input of the next command cook, and that opens the standard input (as a separate file descriptor) and reads that.






share|improve this answer


















  • 2





    Is this method limited to commands that take only one argument? If cook takes two file arguments, and I have the_recipe1 and the_recipe2 (both of which are string variables), will this method still work?

    – Flux
    Mar 12 at 10:18







  • 5





    @Flux You can do it with /dev/fd but that's beyond the scope of your initial question. But I think you'll find examples of that in unix.stackexchange.com/questions/tagged/file-descriptors

    – Gilles
    Mar 12 at 10:24











  • This is not 100% portable, though it does come pretty close in practice: unix.stackexchange.com/q/36403/91565

    – Kevin
    Mar 12 at 21:38


















36














One other way to use the process-substitution feature of the bash shell causes a FIFO to be created under /tmp or /var/tmp, or uses a named file descriptor (/dev/fd/*), depending on the operating system. The substitution syntax (<(cmd)) is replaced by the name of the FIFO or FD, and the command inside it is run in the background.



cook <(printf '%sn' "$the_recipe")


The command cook now reads the content of the variable as if it were available in a file.



This could also be used for more than one input file:



cook <(printf '%sn' "$the_1st_recipe") <(printf '%sn' "$the_2nd_recipe")





share|improve this answer




















  • 4





    Alternatively, cat <<<"$the_recipe" inside the process substitution.

    – Kusalananda
    Mar 12 at 10:25






  • 5





    Note that process substitution is a ksh feature (now also supported by zsh and bash). Chances are cook will expect a text file, so you should probably make it '%sn' instead of '%s'. See also <(<<<$the_recipe) in zsh.

    – Stéphane Chazelas
    Mar 12 at 10:30


















18














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.



Anonymous pipe



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 '%sn' "$the_recipe" | cook # passes $the_recipe plus a final newline


Don't use 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 '%sn' "$the_recipe" | cook -


If the application needs an actual file name, pass /dev/stdin to mean standard input.



printf '%sn' "$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.



Named pipe



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.



mkfifo named.pipe
printf '%sn' "$the_recipe" >named.pipe & writer=$!
cook named.pipe
rm named.pipe
wait "$writer"


(Error checking omitted.)



Temporary file



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).



cook <<<"$the_recipe"


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 … >/tmp/temp.$$! 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.



tmp=
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
tmp=$(mktemp)
printf '%sn' "$the_recipe" >"$tmp"
cook "$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:



tmp=$(TMPDIR="$PWD" mktemp)


(Using $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.



tmp=
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
tmp=$(mktemp -d)
printf '%sn' "$the_recipe" >"$tmp/myfile.ext"
cook "$tmp/myfile.ext"





share|improve this answer























  • I'm pretty sure you can use a here-doc as input, too (I think you might have to use <(cat <<END) or similar; it's years since I've done that).

    – Toby Speight
    Mar 12 at 13:17


















1














Always check if your version of cook supports the argument - (dash) as a filename before trying more complicated solutions. If this convention is supported, it tells cook to read from the standard input, like so:



echo "$the_recipe" | cook -


or



cook - <<<"$the_recipe"





share|improve this answer































    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    40














    You can use the "fake" filename /dev/stdin which represents the standard input.



    So execute this:



    echo "$the_recipe" | cook /dev/stdin


    The echo command and the pipe sends the contents of the specified variable to the standard input of the next command cook, and that opens the standard input (as a separate file descriptor) and reads that.






    share|improve this answer


















    • 2





      Is this method limited to commands that take only one argument? If cook takes two file arguments, and I have the_recipe1 and the_recipe2 (both of which are string variables), will this method still work?

      – Flux
      Mar 12 at 10:18







    • 5





      @Flux You can do it with /dev/fd but that's beyond the scope of your initial question. But I think you'll find examples of that in unix.stackexchange.com/questions/tagged/file-descriptors

      – Gilles
      Mar 12 at 10:24











    • This is not 100% portable, though it does come pretty close in practice: unix.stackexchange.com/q/36403/91565

      – Kevin
      Mar 12 at 21:38















    40














    You can use the "fake" filename /dev/stdin which represents the standard input.



    So execute this:



    echo "$the_recipe" | cook /dev/stdin


    The echo command and the pipe sends the contents of the specified variable to the standard input of the next command cook, and that opens the standard input (as a separate file descriptor) and reads that.






    share|improve this answer


















    • 2





      Is this method limited to commands that take only one argument? If cook takes two file arguments, and I have the_recipe1 and the_recipe2 (both of which are string variables), will this method still work?

      – Flux
      Mar 12 at 10:18







    • 5





      @Flux You can do it with /dev/fd but that's beyond the scope of your initial question. But I think you'll find examples of that in unix.stackexchange.com/questions/tagged/file-descriptors

      – Gilles
      Mar 12 at 10:24











    • This is not 100% portable, though it does come pretty close in practice: unix.stackexchange.com/q/36403/91565

      – Kevin
      Mar 12 at 21:38













    40












    40








    40







    You can use the "fake" filename /dev/stdin which represents the standard input.



    So execute this:



    echo "$the_recipe" | cook /dev/stdin


    The echo command and the pipe sends the contents of the specified variable to the standard input of the next command cook, and that opens the standard input (as a separate file descriptor) and reads that.






    share|improve this answer













    You can use the "fake" filename /dev/stdin which represents the standard input.



    So execute this:



    echo "$the_recipe" | cook /dev/stdin


    The echo command and the pipe sends the contents of the specified variable to the standard input of the next command cook, and that opens the standard input (as a separate file descriptor) and reads that.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Mar 12 at 10:02









    wurtelwurtel

    11k11628




    11k11628







    • 2





      Is this method limited to commands that take only one argument? If cook takes two file arguments, and I have the_recipe1 and the_recipe2 (both of which are string variables), will this method still work?

      – Flux
      Mar 12 at 10:18







    • 5





      @Flux You can do it with /dev/fd but that's beyond the scope of your initial question. But I think you'll find examples of that in unix.stackexchange.com/questions/tagged/file-descriptors

      – Gilles
      Mar 12 at 10:24











    • This is not 100% portable, though it does come pretty close in practice: unix.stackexchange.com/q/36403/91565

      – Kevin
      Mar 12 at 21:38












    • 2





      Is this method limited to commands that take only one argument? If cook takes two file arguments, and I have the_recipe1 and the_recipe2 (both of which are string variables), will this method still work?

      – Flux
      Mar 12 at 10:18







    • 5





      @Flux You can do it with /dev/fd but that's beyond the scope of your initial question. But I think you'll find examples of that in unix.stackexchange.com/questions/tagged/file-descriptors

      – Gilles
      Mar 12 at 10:24











    • This is not 100% portable, though it does come pretty close in practice: unix.stackexchange.com/q/36403/91565

      – Kevin
      Mar 12 at 21:38







    2




    2





    Is this method limited to commands that take only one argument? If cook takes two file arguments, and I have the_recipe1 and the_recipe2 (both of which are string variables), will this method still work?

    – Flux
    Mar 12 at 10:18






    Is this method limited to commands that take only one argument? If cook takes two file arguments, and I have the_recipe1 and the_recipe2 (both of which are string variables), will this method still work?

    – Flux
    Mar 12 at 10:18





    5




    5





    @Flux You can do it with /dev/fd but that's beyond the scope of your initial question. But I think you'll find examples of that in unix.stackexchange.com/questions/tagged/file-descriptors

    – Gilles
    Mar 12 at 10:24





    @Flux You can do it with /dev/fd but that's beyond the scope of your initial question. But I think you'll find examples of that in unix.stackexchange.com/questions/tagged/file-descriptors

    – Gilles
    Mar 12 at 10:24













    This is not 100% portable, though it does come pretty close in practice: unix.stackexchange.com/q/36403/91565

    – Kevin
    Mar 12 at 21:38





    This is not 100% portable, though it does come pretty close in practice: unix.stackexchange.com/q/36403/91565

    – Kevin
    Mar 12 at 21:38













    36














    One other way to use the process-substitution feature of the bash shell causes a FIFO to be created under /tmp or /var/tmp, or uses a named file descriptor (/dev/fd/*), depending on the operating system. The substitution syntax (<(cmd)) is replaced by the name of the FIFO or FD, and the command inside it is run in the background.



    cook <(printf '%sn' "$the_recipe")


    The command cook now reads the content of the variable as if it were available in a file.



    This could also be used for more than one input file:



    cook <(printf '%sn' "$the_1st_recipe") <(printf '%sn' "$the_2nd_recipe")





    share|improve this answer




















    • 4





      Alternatively, cat <<<"$the_recipe" inside the process substitution.

      – Kusalananda
      Mar 12 at 10:25






    • 5





      Note that process substitution is a ksh feature (now also supported by zsh and bash). Chances are cook will expect a text file, so you should probably make it '%sn' instead of '%s'. See also <(<<<$the_recipe) in zsh.

      – Stéphane Chazelas
      Mar 12 at 10:30















    36














    One other way to use the process-substitution feature of the bash shell causes a FIFO to be created under /tmp or /var/tmp, or uses a named file descriptor (/dev/fd/*), depending on the operating system. The substitution syntax (<(cmd)) is replaced by the name of the FIFO or FD, and the command inside it is run in the background.



    cook <(printf '%sn' "$the_recipe")


    The command cook now reads the content of the variable as if it were available in a file.



    This could also be used for more than one input file:



    cook <(printf '%sn' "$the_1st_recipe") <(printf '%sn' "$the_2nd_recipe")





    share|improve this answer




















    • 4





      Alternatively, cat <<<"$the_recipe" inside the process substitution.

      – Kusalananda
      Mar 12 at 10:25






    • 5





      Note that process substitution is a ksh feature (now also supported by zsh and bash). Chances are cook will expect a text file, so you should probably make it '%sn' instead of '%s'. See also <(<<<$the_recipe) in zsh.

      – Stéphane Chazelas
      Mar 12 at 10:30













    36












    36








    36







    One other way to use the process-substitution feature of the bash shell causes a FIFO to be created under /tmp or /var/tmp, or uses a named file descriptor (/dev/fd/*), depending on the operating system. The substitution syntax (<(cmd)) is replaced by the name of the FIFO or FD, and the command inside it is run in the background.



    cook <(printf '%sn' "$the_recipe")


    The command cook now reads the content of the variable as if it were available in a file.



    This could also be used for more than one input file:



    cook <(printf '%sn' "$the_1st_recipe") <(printf '%sn' "$the_2nd_recipe")





    share|improve this answer















    One other way to use the process-substitution feature of the bash shell causes a FIFO to be created under /tmp or /var/tmp, or uses a named file descriptor (/dev/fd/*), depending on the operating system. The substitution syntax (<(cmd)) is replaced by the name of the FIFO or FD, and the command inside it is run in the background.



    cook <(printf '%sn' "$the_recipe")


    The command cook now reads the content of the variable as if it were available in a file.



    This could also be used for more than one input file:



    cook <(printf '%sn' "$the_1st_recipe") <(printf '%sn' "$the_2nd_recipe")






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Mar 12 at 10:32

























    answered Mar 12 at 10:05









    InianInian

    5,1151429




    5,1151429







    • 4





      Alternatively, cat <<<"$the_recipe" inside the process substitution.

      – Kusalananda
      Mar 12 at 10:25






    • 5





      Note that process substitution is a ksh feature (now also supported by zsh and bash). Chances are cook will expect a text file, so you should probably make it '%sn' instead of '%s'. See also <(<<<$the_recipe) in zsh.

      – Stéphane Chazelas
      Mar 12 at 10:30












    • 4





      Alternatively, cat <<<"$the_recipe" inside the process substitution.

      – Kusalananda
      Mar 12 at 10:25






    • 5





      Note that process substitution is a ksh feature (now also supported by zsh and bash). Chances are cook will expect a text file, so you should probably make it '%sn' instead of '%s'. See also <(<<<$the_recipe) in zsh.

      – Stéphane Chazelas
      Mar 12 at 10:30







    4




    4





    Alternatively, cat <<<"$the_recipe" inside the process substitution.

    – Kusalananda
    Mar 12 at 10:25





    Alternatively, cat <<<"$the_recipe" inside the process substitution.

    – Kusalananda
    Mar 12 at 10:25




    5




    5





    Note that process substitution is a ksh feature (now also supported by zsh and bash). Chances are cook will expect a text file, so you should probably make it '%sn' instead of '%s'. See also <(<<<$the_recipe) in zsh.

    – Stéphane Chazelas
    Mar 12 at 10:30





    Note that process substitution is a ksh feature (now also supported by zsh and bash). Chances are cook will expect a text file, so you should probably make it '%sn' instead of '%s'. See also <(<<<$the_recipe) in zsh.

    – Stéphane Chazelas
    Mar 12 at 10:30











    18














    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.



    Anonymous pipe



    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 '%sn' "$the_recipe" | cook # passes $the_recipe plus a final newline


    Don't use 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 '%sn' "$the_recipe" | cook -


    If the application needs an actual file name, pass /dev/stdin to mean standard input.



    printf '%sn' "$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.



    Named pipe



    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.



    mkfifo named.pipe
    printf '%sn' "$the_recipe" >named.pipe & writer=$!
    cook named.pipe
    rm named.pipe
    wait "$writer"


    (Error checking omitted.)



    Temporary file



    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).



    cook <<<"$the_recipe"


    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 … >/tmp/temp.$$! 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.



    tmp=
    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
    tmp=$(mktemp)
    printf '%sn' "$the_recipe" >"$tmp"
    cook "$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:



    tmp=$(TMPDIR="$PWD" mktemp)


    (Using $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.



    tmp=
    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
    tmp=$(mktemp -d)
    printf '%sn' "$the_recipe" >"$tmp/myfile.ext"
    cook "$tmp/myfile.ext"





    share|improve this answer























    • I'm pretty sure you can use a here-doc as input, too (I think you might have to use <(cat <<END) or similar; it's years since I've done that).

      – Toby Speight
      Mar 12 at 13:17















    18














    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.



    Anonymous pipe



    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 '%sn' "$the_recipe" | cook # passes $the_recipe plus a final newline


    Don't use 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 '%sn' "$the_recipe" | cook -


    If the application needs an actual file name, pass /dev/stdin to mean standard input.



    printf '%sn' "$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.



    Named pipe



    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.



    mkfifo named.pipe
    printf '%sn' "$the_recipe" >named.pipe & writer=$!
    cook named.pipe
    rm named.pipe
    wait "$writer"


    (Error checking omitted.)



    Temporary file



    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).



    cook <<<"$the_recipe"


    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 … >/tmp/temp.$$! 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.



    tmp=
    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
    tmp=$(mktemp)
    printf '%sn' "$the_recipe" >"$tmp"
    cook "$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:



    tmp=$(TMPDIR="$PWD" mktemp)


    (Using $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.



    tmp=
    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
    tmp=$(mktemp -d)
    printf '%sn' "$the_recipe" >"$tmp/myfile.ext"
    cook "$tmp/myfile.ext"





    share|improve this answer























    • I'm pretty sure you can use a here-doc as input, too (I think you might have to use <(cat <<END) or similar; it's years since I've done that).

      – Toby Speight
      Mar 12 at 13:17













    18












    18








    18







    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.



    Anonymous pipe



    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 '%sn' "$the_recipe" | cook # passes $the_recipe plus a final newline


    Don't use 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 '%sn' "$the_recipe" | cook -


    If the application needs an actual file name, pass /dev/stdin to mean standard input.



    printf '%sn' "$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.



    Named pipe



    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.



    mkfifo named.pipe
    printf '%sn' "$the_recipe" >named.pipe & writer=$!
    cook named.pipe
    rm named.pipe
    wait "$writer"


    (Error checking omitted.)



    Temporary file



    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).



    cook <<<"$the_recipe"


    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 … >/tmp/temp.$$! 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.



    tmp=
    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
    tmp=$(mktemp)
    printf '%sn' "$the_recipe" >"$tmp"
    cook "$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:



    tmp=$(TMPDIR="$PWD" mktemp)


    (Using $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.



    tmp=
    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
    tmp=$(mktemp -d)
    printf '%sn' "$the_recipe" >"$tmp/myfile.ext"
    cook "$tmp/myfile.ext"





    share|improve this answer













    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.



    Anonymous pipe



    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 '%sn' "$the_recipe" | cook # passes $the_recipe plus a final newline


    Don't use 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 '%sn' "$the_recipe" | cook -


    If the application needs an actual file name, pass /dev/stdin to mean standard input.



    printf '%sn' "$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.



    Named pipe



    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.



    mkfifo named.pipe
    printf '%sn' "$the_recipe" >named.pipe & writer=$!
    cook named.pipe
    rm named.pipe
    wait "$writer"


    (Error checking omitted.)



    Temporary file



    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).



    cook <<<"$the_recipe"


    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 … >/tmp/temp.$$! 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.



    tmp=
    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
    tmp=$(mktemp)
    printf '%sn' "$the_recipe" >"$tmp"
    cook "$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:



    tmp=$(TMPDIR="$PWD" mktemp)


    (Using $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.



    tmp=
    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
    tmp=$(mktemp -d)
    printf '%sn' "$the_recipe" >"$tmp/myfile.ext"
    cook "$tmp/myfile.ext"






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Mar 12 at 10:22









    GillesGilles

    542k12810991616




    542k12810991616












    • I'm pretty sure you can use a here-doc as input, too (I think you might have to use <(cat <<END) or similar; it's years since I've done that).

      – Toby Speight
      Mar 12 at 13:17

















    • I'm pretty sure you can use a here-doc as input, too (I think you might have to use <(cat <<END) or similar; it's years since I've done that).

      – Toby Speight
      Mar 12 at 13:17
















    I'm pretty sure you can use a here-doc as input, too (I think you might have to use <(cat <<END) or similar; it's years since I've done that).

    – Toby Speight
    Mar 12 at 13:17





    I'm pretty sure you can use a here-doc as input, too (I think you might have to use <(cat <<END) or similar; it's years since I've done that).

    – Toby Speight
    Mar 12 at 13:17











    1














    Always check if your version of cook supports the argument - (dash) as a filename before trying more complicated solutions. If this convention is supported, it tells cook to read from the standard input, like so:



    echo "$the_recipe" | cook -


    or



    cook - <<<"$the_recipe"





    share|improve this answer





























      1














      Always check if your version of cook supports the argument - (dash) as a filename before trying more complicated solutions. If this convention is supported, it tells cook to read from the standard input, like so:



      echo "$the_recipe" | cook -


      or



      cook - <<<"$the_recipe"





      share|improve this answer



























        1












        1








        1







        Always check if your version of cook supports the argument - (dash) as a filename before trying more complicated solutions. If this convention is supported, it tells cook to read from the standard input, like so:



        echo "$the_recipe" | cook -


        or



        cook - <<<"$the_recipe"





        share|improve this answer















        Always check if your version of cook supports the argument - (dash) as a filename before trying more complicated solutions. If this convention is supported, it tells cook to read from the standard input, like so:



        echo "$the_recipe" | cook -


        or



        cook - <<<"$the_recipe"






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Mar 13 at 14:59









        wjandrea

        502413




        502413










        answered Mar 13 at 10:00









        rackandbonemanrackandboneman

        39915




        39915













            Popular posts from this blog

            How should I support this large drywall patch? Planned maintenance scheduled April 23, 2019 at 00:00UTC (8:00pm US/Eastern) Announcing the arrival of Valued Associate #679: Cesar Manara Unicorn Meta Zoo #1: Why another podcast?How do I cover large gaps in drywall?How do I keep drywall around a patch from crumbling?Can I glue a second layer of drywall?How to patch long strip on drywall?Large drywall patch: how to avoid bulging seams?Drywall Mesh Patch vs. Bulge? To remove or not to remove?How to fix this drywall job?Prep drywall before backsplashWhat's the best way to fix this horrible drywall patch job?Drywall patching using 3M Patch Plus Primer

            random experiment with two different functions on unit interval Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 00:00UTC (8:00pm US/Eastern)Random variable and probability space notionsRandom Walk with EdgesFinding functions where the increase over a random interval is Poisson distributedNumber of days until dayCan an observed event in fact be of zero probability?Unit random processmodels of coins and uniform distributionHow to get the number of successes given $n$ trials , probability $P$ and a random variable $X$Absorbing Markov chain in a computer. Is “almost every” turned into always convergence in computer executions?Stopped random walk is not uniformly integrable

            Lowndes Grove History Architecture References Navigation menu32°48′6″N 79°57′58″W / 32.80167°N 79.96611°W / 32.80167; -79.9661132°48′6″N 79°57′58″W / 32.80167°N 79.96611°W / 32.80167; -79.9661178002500"National Register Information System"Historic houses of South Carolina"Lowndes Grove""+32° 48' 6.00", −79° 57' 58.00""Lowndes Grove, Charleston County (260 St. Margaret St., Charleston)""Lowndes Grove"The Charleston ExpositionIt Happened in South Carolina"Lowndes Grove (House), Saint Margaret Street & Sixth Avenue, Charleston, Charleston County, SC(Photographs)"Plantations of the Carolina Low Countrye