Shell Cannot cat into file?

I cannot run a basic cat on FreeBSD 12.2-RELEASE-p2? Thank you for letting me know what am I doing wrong.

Code:
cat > ~/test.sh << 'EOF'
#!/bin/sh

echo 'This is a string'
echo "And a $variable"
EOF

The file cannot be saved.
 
Syntax between a Bourne compatible shell and the C shells is a little different.
 
Narrowly speaking, here documents are file literals or stream literals. These originate in the Unix shell, though similar facilities are available in some other languages.

[mod: Don't copy/paste the entire Wikipedia article, a link is good enough and has already been provided]
 
Thank you all, using the suggested example still does not work:
Code:
cat > ~/test.sh << 'EOF'
#!/bin/sh

echo 1
echo 2
EOF

This is the output I get:

1611852477860.png


The file is simply not saved, is like it could not see the EOF at end. If I remove the EOF quotes, the code works, except shebang or variables will not be preserved:
Code:
# cat > ~/test.sh << EOF
? #!/bin/sh
?
? echo 'This is a string'
? echo "And a $variable"
variable: Undefined variable.
# EOF

Edit: I understand now, but this is not listed into that documentation, I have to match 'EOF':
Code:
# cat > ~/test.sh << 'EOF'
? #!/bin/sh
?
? echo 'This is a string'
? echo "And a $variable"
? 'EOF'

# cat ~/test.sh
#!/bin/sh

echo 'This is a string'
echo "And a $variable"

1611853558797.png
 
Did you try this:

cat << EOF > ~/test.sh
The order does not matter. I posted above the fix with explanation in an edit. There are small changes in FreeBSD that break Linux user habits. :) Basically, you need to literally match 'EOF' at end, not EOF. In Linux, EOF will work fine.
 
Works fine on csh(1):
Code:
root@molly:~ # cat > /tmp/test << EOF
? echo hi
? EOF
root@molly:~ # cat /tmp/test
echo hi
Code:
root@molly:~ # rm /tmp/test
root@molly:~ # cat <<EOF > /tmp/test
? echo hi
? EOF
root@molly:~ # cat /tmp/test
echo hi
 
Like this?
Code:
root@molly:~ # cat > /tmp/test << EOF
? #!/bin/sh
? var=hi
? echo \$var
? EOF
root@molly:~ # cat /tmp/test
#!/bin/sh
var=hi
echo $var
root@molly:~ # sh /tmp/test
hi
 
You escaped the variable, the goal I'm trying to accomplish is create a VERY long shell script file (which already exists), without editing the literal content of the script or fiddle with escapes, etc. You can accomplish this in Linux with the following format:

Code:
cat > ~/test.sh << 'EOF'
#!/bin/sh

echo 'This is a string'
echo "And a $variable"
EOF

In FreeBSD you need to single quote at beginning as well end, not just beginning:

Code:
cat > ~/test.sh << 'EOF'
#!/bin/sh

echo 'This is a string'
echo "And a $variable"
'EOF'

That is what caught me off guard, I never saw this before.
 
You have to escape it because you need a literal $ in the file. Or else the shell is going to interpret it when you enter it.
Code:
root@molly:~ # setenv var foo
root@molly:~ # cat > /tmp/test << EOF
? var=bar
? echo $var
? EOF
root@molly:~ # cat /tmp/test
var=bar
echo foo
Works the same way in sh(1) and bash(1):
Code:
root@molly:~ # /bin/sh
# var=foo
# cat > /tmp/test << EOF
> var=bar
> echo $var
> EOF
# cat /tmp/test
var=bar
echo foo
# ^D
root@molly:~ # bash
[root@molly ~]# var=foo
[root@molly ~]# cat > /tmp/test << EOF
> var=bar
> echo $var
> EOF
[root@molly ~]# cat /tmp/test
var=bar
echo foo
[root@molly ~]#
 
You can avoid escaping variables, just by single quoting your opening EOF delimiter. The difference between Linux and Unix is that for later you will need to also single quote your closing EOF delimiter.
 
Back
Top