bash run script from here doc [duplicate] - bash

This question already has answers here:
Using variables inside a bash heredoc
(3 answers)
Closed 3 years ago.
In the code below, variable X is output normally.
# cat a.sh
X=world
echo 'hello' $X
# cat a.sh | bash
hello world
But, using here doc, variable X is not displayed.
# cat <<EOF | bash
> X=world
> echo 'hello' $X
> EOF
hello
# bash -s <<EOF
> X=world
> echo 'hello' $X
> EOF
hello
What made this difference?

You can see what happens when you remove the |bash
X=oldvalue
cat <<EOF
X=world
echo "hello $X"
EOF
The $X is replaced before piping it to bash.
You can check the following
X=oldvalue
cat <<"EOF"
X=world
echo "hello $X"
EOF
This is what you want to execute:
cat <<"EOF" | bash
X=world
echo "hello $X"
EOF

Related

How do I get a variable value that is stored in a string in a file?

I have a file with strings that include variables. I want to retrieve the string with the value of the variable being represented in the string. I have tried ${!var} without success.
A file called test.line with the string and a variable:
$ cat test.line
Hello $var3
A bash script called test.sh:
$ cat test.sh
#!/bin/bash
var1="hello"
var2="goodbye"
var3="again"
## works
str="$var1 and $var2"
echo $str
## does not work--prints $var3 instead of "again"
str="$(cat test.line)"
echo $str
Output of test.sh when run:
$ ./test.sh
hello and goodbye
Hello $var3
Desired output of test.sh when run:
$ ./test.sh
hello and goodbye
Hello again
$ cat test.sh
#!/bin/bash
var1="hello"
var2="goodbye"
var3="again"
## works
str="$var1 and $var2"
echo $str
## SOLVED -- Does work
str="$(cat test.line)"
eval echo $str # This is the line that SOLVED it
Output of test.sh when run:
$ ./test.sh
hello and goodbye
Hello again ##This is what I want (SOLVED)

STDIN Pipe file into for loop

I was wondering is there a way that i can enter
./myscript.sh FILENAME
and the file will link into
for a in $(cat FILENAME) ; do
done
Calling your script with:
./myscript.sh babynames
You can process each line of you file with read:
while read -r line; do
echo "$line"
done < "$1"
$ cat > myscript.sh # create myscript.sh
for i in "$(cat $1)" ; do echo "$i" ; done # in the end CTRL-d
$ cat > babynames # create babynames
primo
secundo # in the end CTRL-d
$ bash myscript.sh babynames # execute the script with babynames as parameter
primo
secundo

Why is "while read -r a" command unable to read string that is not newline terminated?

Here is my shell script.
printf "foo" | (read -r a; echo $a)
printf "bar" | while read -r a
do
echo $a
done
Here is the output.
$ sh foo.sh
foo
My question is: Why is foo printed but bar not printed? When read -r a is able to read a string that is not newline-terminated why is it unable to do so when it used as a condition of a while loop?

writing file using cat with here-document

$ cat > out.txt <<EOF
> Hello world
> EOF
$
How do I do this in single statement?
Somethig like 'echo' in following statement
$ for i in {1..5}; do echo "Hello world" > out_$i.txt; done
You can use a here-string, which is a shortcut for short here documents in bash.
cat <<< "Hello world" > out.txt

Prevent bash from interpreting without quoting everything

I need to output some text as bash script, but in a script. I use cat for this, but it has one drawback. It interprets variables and stuff during it is being written. I do want to prevent this.
How to do that without quoting all varibles (my script is failrly long)? Example
cat >/tmp/script << EOF
$HOSTNAME
# lots of other stuff I do NOT want to escape like \$VARIABLE
# ...
EOF
cat /tmp/script
myhostname.mylan
I want:
cat /tmp/script
$HOSTNAME
Edit: Please note my script (here only $HOSTNAME) is very long, I dont want to change it all. Also single quoting does not work with <<
cat >/tmp/script '<< EOF
$HOSTNAME
EOF'
File not found: EOF'
What's the trick? Thanks.
If you want everything quoted:
cat << 'EOF'
stuff here with $signs is OK
as are `backquotes`
EOF
See the section on "here documents" in the manual.
Escape the $:
cat >/tmp/script << EOF
\$HOSTNAME
EOF
Use sed:
sed -n '20,30p' "$0"
to print line 20 to 30, SSCE:
#!/bin/bash
cat >/dev/null << EOF
3
4 $HOSTNAME
5 ls
6 $(ls -l)
7
8 echo 'foo
9 bar'
10
11 echo "Foo
12 $((4+4)) Bar"
EOF
sed -n '3,12p' "$0"
echo "fine?"
working with head/tail should work too.
You will have to adjust the numbers, if you work on it and insert or delete lines.

Resources