How to Cat ≪≪Eof ≫≫ a File Containing Code

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

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



Leave a reply



Submit