How can pass the value of a variable to the standard input of a command?
I'm writing a shell script that should be somewhat secure, i.e., does not pass secure data through parameters of commands and preferably does not use temporary files. How can I pass a variable to the standard input of a command?
Or, if it's not possible, how can I correctly use temporary files for such a task?
Solution 1:
Passing a value to standard input in Bash is as simple as:
your-command <<< "$your_variable"
Always make sure you put quotes around variable expressions!
Be cautious, that this will probably work only in
bash
and will not work insh
.
Solution 2:
Simple, but error-prone: using echo
Something as simple as this will do the trick:
echo "$blah" | my_cmd
Do note that this may not work correctly if $blah
contains -n
, -e
, -E
etc; or if it contains backslashes (bash's copy of echo
preserves literal backslashes in absence of -e
by default, but will treat them as escape sequences and replace them with corresponding characters even without -e
if optional XSI extensions are enabled).
More sophisticated approach: using printf
printf '%s\n' "$blah" | my_cmd
This does not have the disadvantages listed above: all possible C strings (strings not containing NULs) are printed unchanged.
Solution 3:
Note that the 'echo "$var" | command
operations mean that standard input is limited to the line(s) echoed. If you also want the terminal to be connected, then you'll need to be fancier:
{ echo "$var"; cat - ; } | command
( echo "$var"; cat - ) | command
This means that the first line(s) will be the contents of $var
but the rest will come from cat
reading its standard input. If the command does not do anything too fancy (try to turn on command line editing, or run like vim
does) then it will be fine. Otherwise, you need to get really fancy - I think expect
or one of its derivatives is likely to be appropriate.
The command line notations are practically identical - but the second semi-colon is necessary with the braces whereas it is not with parentheses.
Solution 4:
(cat <<END
$passwd
END
) | command
The cat
is not really needed, but it helps to structure the code better and allows you to use more commands in parentheses as input to your command.