How to cat EOF a file containing code?
You only need a minimal change; single-quote the here-document delimiter after <<
.
cat <<'EOF' >> brightup.sh
or equivalently backslash-escape it:
cat <<\EOF >>brightup.sh
Without quoting, the here document will undergo variable substitution, backticks will be evaluated, etc, like you discovered.
If you need to expand some, but not all, values, you need to individually escape the ones you want to prevent.
cat <<EOF >>brightup.sh
#!/bin/sh
# Created on $(date # : <<-- this will be evaluated before cat;)
echo "\$HOME will not be evaluated because it is backslash-escaped"
EOF
will produce
#!/bin/sh
# Created on Fri Feb 16 11:00:18 UTC 2018
echo "$HOME will not be evaluated because it is backslash-escaped"
As suggested by @fedorqui, here is the relevant section from man bash
:
Here Documents
This type of redirection instructs the shell to read input from the
current source until a line containing only delimiter (with no
trailing blanks) is seen. All of the lines read up to that point are
then used as the standard input for a command.The format of here-documents is:
<<[-]word
here-document
delimiterNo parameter expansion, command substitution, arithmetic expansion,
or pathname expansion is performed on word. If any characters in word
are quoted, the delimiter is the result of quote removal on word, and
the lines in the here-document are not expanded. If word is
unquoted, all lines of the here-document are subjected to parameter
expansion, command substitution, and arithmetic expansion. In the
latter case, the character sequence\<newline>
is ignored, and\
must be used to quote the characters\
,$
, and`
.
How does cat EOF work in bash?
This is called heredoc format to provide a string into stdin. See https://en.wikipedia.org/wiki/Here_document#Unix_shells for more details.
From man bash
:
Here Documents
This type of redirection instructs the shell to read input from
the current source until a line
containing only word (with no trailing
blanks) is seen.All of the lines read up to that point are then used as the
standard input for a command.The format of here-documents is:
<<[-]word
here-document
delimiter
No parameter expansion, command substitution, arithmetic expansion, or
pathname expansion is performed on
word. If any characters in word are
quoted, the
delimiter is the result of quote removal on word, and the lines
in the here-document are not expanded.
If word is unquoted, all lines of the
here-document are subjected to parameter expansion, command
substitution, and arithmetic
expansion. In the latter case, the
character sequence\<newline>
is
ignored, and\
must be used to quote the characters\
,$
, and`
.If the redirection operator is
<<-
, then all leading tab characters
are stripped from input lines and the
line containing delimiter. This
allows here-documents within shell scripts to be indented in a natural fashion.
How can I read a file in cat EOF
You could use backticks, or write the file in chunks:
#!/bin/bash
cat <<OMG >zfile
ad3
c43
34e
se3
we3
OMG
# Method1 : backticks
cat << EOF > test.sh
#!/bin/bash
some commands1
`cat zfile`
some commands2
EOF
# Method2: append
cat << EOF1 > test2.sh
#!/bin/bash
some commands1
EOF1
cat zfile >> test2.sh
cat << EOF2 >> test2.sh
some commands2
EOF2
How can I write a heredoc to a file in Bash script?
Read the Advanced Bash-Scripting Guide Chapter 19. Here Documents.
Here's an example which will write the contents to a file at /tmp/yourfilehere
cat << EOF > /tmp/yourfilehere
These contents will be written to the file.
This line is indented.
EOF
Note that the final 'EOF' (The LimitString
) should not have any whitespace in front of the word, because it means that the LimitString
will not be recognized.
In a shell script, you may want to use indentation to make the code readable, however this can have the undesirable effect of indenting the text within your here document. In this case, use <<-
(followed by a dash) to disable leading tabs (Note that to test this you will need to replace the leading whitespace with a tab character, since I cannot print actual tab characters here.)
#!/usr/bin/env bash
if true ; then
cat <<- EOF > /tmp/yourfilehere
The leading tab is ignored.
EOF
fi
If you don't want to interpret variables in the text, then use single quotes:
cat << 'EOF' > /tmp/yourfilehere
The variable $FOO will not be interpreted.
EOF
To pipe the heredoc through a command pipeline:
cat <<'EOF' | sed 's/a/b/'
foo
bar
baz
EOF
Output:
foo
bbr
bbz
... or to write the the heredoc to a file using sudo
:
cat <<'EOF' | sed 's/a/b/' | sudo tee /etc/config_file.conf
foo
bar
baz
EOF
How create file via function using cat in Bash scenario
even if available in bash, the function
is not necessary and BTW is not standard
The declaration should probably be
myfunc () {
and call does not need them:
myfunc "$vID" "$pID"
Nested for loop with cat EOF issues
When you do << EOF
the exactly whole line has to be EOF
with no spaces, nor tabs, not before nor after the EOF
string.
Do:
cat << EOF >> ./algo/job_$j.sh
#!/bin/bash -l
#
#$ -N $i
#$ -cwd
#$ -pe smp 10
#$ -l mem_free=20G
algo --input_se $i --output $j --threads=10
EOF
^ no spaces after
^ no spaces in front
Alternatively you can use << -EOF
and leading tabs (and tabs only!) will be ignored.
Notes:
- Do not use backticks `. Use
$(..)
intead. https://wiki-dev.bash-hackers.org/scripting/obsolete for i in cat
is an antipattern. How to read a file line by line in bash.
how i would use while read instead to read a file line by line in my case?
while IFS= read -r x; do
while IFS= read -r y; do
something something
done < y_list
done < x_file_locations
Using and variable file name
Escape the $
to prevent the shell from expanding $FILE
:
if [ ! -e "\$FILE" ]; then
echo "min_granularity_ns" > \$FILE
fi
Note: This is not a great answer, but it does explain the problem: variable expansion before the here doc is created. So, I'm leaving it for now.
Is it safe to use cat -EOF
You should realize that some users set their editors to automatically convert tabs into spaces. So when you work with multiple users on the same script, it is paramount to set up some base rules for this, which is annoying as you will end up with a one-day tab-vs-spaces war. Furthermore, I often consider tabs evil. They are good as a field separator, but they are awful when visualization depends on it. Everything depends on where the tabstops are defined and this can change from editor to editor and terminal to terminal. Sometimes. the tabstops are defined as a multiple of 8, sometimes as a multiple of 4. There is even the Posix command tabs
which allows you to set the tabstops in any way you want
$ tabs 1,6,10,14,18,22,26,30,34,38,42,46,50,54,58,62,67
So ... tabs are evil!
My suggestion to you is to use the following:
printf "%s\n" 'fantastic line1' \
'awesome line2' \
'amazing line3' \
'unrivaled line4'
bash script within EOF unable to pass arguments to function
Quote the << 'EOF'
to prevent the $
in the function from being expanded before the function is defined.
sudo -i -u $USER bash << 'EOF'
func(){
echo $1
}
func 'Test message for channel'
EOF
See the Bash manual on Here Documents. This behaviour applies to all Bourne shell derivatives — Bash, POSIX shells, ksh
, etc.
Related Topics
How to Grep For Contents After Pattern
Linux Blocking Vs. Non Blocking Serial Read
Aborting a Shell Script If Any Command Returns a Non-Zero Value
Get Destination Address of a Received Udp Packet
How to Delete a Newline If It Is the Last Character in a File
How to Open a New Tab in Gnome Terminal from Command Line
How to Deal With a Filename That Starts With the Hyphen (-) Character
Make $Java_Home Easily Changable in Ubuntu
How to Split CSV Files as Per Number of Rows Specified
Understanding User File Ownership in Docker: How to Avoid Changing Permissions of Linked Volumes
Can You Run Gui Applications in a Linux Docker Container
Deploying Yesod to Heroku, Can't Build Statically
What Is the Meaning of So_Reuseaddr (Setsockopt Option) - Linux
Bash While Read Loop Extremely Slow Compared to Cat, Why
How to Compile a 32-Bit Binary on a 64-Bit Linux Machine With Gcc/Cmake
How to Get Cmake to Find My Alternative Boost Installation