Reputation: 11499
Consider this very simple bash script:
#!/bin/bash
cat > /tmp/file
It redirects whatever you pipe into it to a file. e.g.
echo "hello" | script.sh
and "hello" will be in the file /tmp/file. This works... but it seems like there should be a native bash way of doing this without using "cat". But I can't figure it out.
NOTE:
It must be in a script. I want the script to operate on the file contents afterwards.
It must be in a file, the steps afterward in my case involve a tool that only reads from a file.
I already have a pretty good way of doing this - its just that it seems like a hack. Is there a native way? Like "/tmp/file < 0 " or "0> /tmp/file". I thought bash would have a native syntax to do this...
Upvotes: 27
Views: 58129
Reputation: 1
A very good idea: How to read hidden input from terminal and pipe it to another command
If you define an alias:
alias readp='{ read -s -p "Input a secret: "; printf %s $REPLY; }'
then you can do readp | wc -c
Upvotes: 0
Reputation: 1
If you don't want the program to end after reaching EOF, this might be helpful.
#!/bin/bash
exec < <(tail -F /tmp/a)
cat -
Upvotes: 0
Reputation: 413
Another option: dd of=/tmp/myfile/txt
Note: This is not a built-in, however, it might help other people looking for a simple solution.
Upvotes: 5
Reputation: 599
You could simply do
cp /dev/stdin myfile.txt
Terminate your input with Ctrl+D or Ctrl+Z and, viola! You have your file created with text from the stdin.
Upvotes: 59
Reputation: 1650
I don't think there is a builtin that reads from stdin until EOF, but you can do this:
#!/bin/bash
exec > /tmp/file
while IFS= read -r line; do
printf '%s\n' "$line"
done
Upvotes: 8
Reputation: 1216
echo "$(</dev/stdin)" > /tmp/file
terminate your input with ENTERctrl+d
Upvotes: 18
Reputation: 786091
Another way of doing it using pure BASH:
#!/bin/bash
IFS= read -t 0.01 -r -d '' indata
[[ -n $indata ]] && printf "%s" "$indata" >/tmp/file
IFS=
and -d ''
causes all of stdin data to be read into a variable indata
.
Reason of using -t 0.01
: When this script is called with no input pipe then read
will timeout after negligible 0.01
seconds delay. If there is any data available in input it will be read in indata
variable and it will be redirected to >/tmp/file
.
Upvotes: 3
Reputation: 1929
Why don't you just
GENERATE INPUT | (
# do whatever you like to the input here
)
But sometimes, especially when you want to complete the input first, then operate on the modified output, you should still use temporary files:
TMPFILE="/tmp/fileA-$$"
GENERATE INPUT | (
# modify input
) > "$TMPFILE"
(
# do something with the input from TMPFILE
) < "$TMPFILE"
rm "$TMPFILE"
Upvotes: 0