Why "echo <<EOF" not working as expected [duplicate] - bash

This question already has answers here:
Bash here document produces no output, any idea why?
(2 answers)
Closed 5 years ago.
I am trying to understand the bash's here document feature. Below code works as expected and returns "abc" to terminal. If I replace the program cat by echo I do not see any output. Why I am not able to pass here document to echo ? Is it becuase it is a bash builtin ?
cat <<EOF
abc
EOF
"abc" is output to the terminal as expected.
No output for below comamnd though-
echo <<EOF
abc
EOF

You want:
cat <<EOF
abc
EOF
Otherwise, what you're doing is just running echo with its stdin connected to a temporary file having abc in it. Since echo doesn't read stdin, it never finds out if there's contents waiting to be read from there or not.

Related

Bash create file script with echo command [duplicate]

This question already has answers here:
Multi-line string with extra space (preserved indentation)
(12 answers)
Closed 1 year ago.
I need to generate the following file content with the bash script.
#!/bin/sh
script_dir=$(dirname "$(realpath $0)")
export LD_LIBRARY_PATH=$script_dir/lib
exec $script_dir/{EXEC_FILE_WITH_EXT}
i.e. something like
my_script_generator.sh
#!/bin/sh
echo "<filecontent above>" > new_script.sh
The problem's a make all screening correctly to avoid echo evaluate the content and put it just as is.
For the more huge script, it becomes a problem.
Is there an online service that simplifies that work?
Use cat+here-document and backslash before $ signs you dont't want to be evaluated.
#!/bin/sh
cat > new_script.sh <<EOF
#!/bin/sh
script_dir=\$(dirname "\$(realpath \$0)")
export LD_LIBRARY_PATH=\$script_dir/lib
exec \$script_dir/{EXEC_FILE_WITH_EXT}
EOF
A script like this (not bullet proof) could help automate the task
#!/bin/sh
# make-script.sh
# input : a sequence of commands
# output : sequence of commands which generates a copy of the source script file
echo "cat <<EOF"
echo "#!/bin/sh"
echo
sed "s/\\\$/\\\\\\\$/g"
echo "EOF"

Unix cat command, pipe and stdin/stdout [duplicate]

This question already has answers here:
Difference in pipe and file redirection - BASH
(3 answers)
What is a simple explanation for how pipes work in Bash?
(11 answers)
Piping and Redirection
(5 answers)
Closed 2 years ago.
Here is something I don't understand.
Why this works : echo "akka" | cat
But this does not produce "akka" on the console : echo "akka" > cat
And this does not even work : cat < echo "akka"
For me they should be the same. But these 3 commands seem different
You are confusing the differences between file redirection and piping.
The pipe symbol | is used to pass the output of one command into another command.
Meanwhile, < and > are used for file redirection.
These are very different operations.
Example 1:
echo "akka" | cat
The echo command has the output akka, and this is piped into the standard input of the cat command. The cat command writes to standard output, so in this case it prints akka. Of course, this is no different from doing simply:
echo "akka"
Example 2:
echo "akka" > cat
The echo command has the output akka. Using >, this output is then redirected into a file called cat. There is no output shown in the terminal in this case, since the output is placed into a file instead.
Example 3:
cat < echo "akka"
This is quite different from the first two. This runs the cat command, which reads from standard input. Using <, input is passed to the cat command from a file called echo. If no such files exists, then it will produce an error.

source command output lines [duplicate]

This question already has answers here:
How to echo shell commands as they are executed
(14 answers)
Closed 4 years ago.
I want to source a file containing several commands in a bash shell. How can I have the currently executed command printed on top of the commands output?
E.g. given this file test.sh
echo "hello"
echo "world"
the output of source test.sh should be:
echo "hello"
hello
echo "world"
world
Type set -x before source test.sh. This tells the shell to show the commands that are being executed before executing them.
Type set +x to undo it afterwards.

grep behaving differently in bash script than in interactive shell [duplicate]

This question already has answers here:
grep for expression containing variable
(2 answers)
Closed 9 years ago.
In my bash script, I am attempting to parse through a status file and detect errors based on some keywords. I store these prefixes in a list, and then loop through them.
Bash script:
status_page="/path/to/file.txt"
list="aaa bbb ccc ddd"
for pre in $list
do
echo "grep '\w\w\w${pre}-.*\.lin failed' ${status_page}" # debug
if grep '\w\w\w${pre}-.*\.lin failed' ${status_page}; then
echo "Found error!"
exit 8;
fi
done
/path/to/file.txt:
xyzfff-tool.lin failed
xyzggg-exec.lin failed
rstccc-tool.lin failed
The bash script should catch the line rstccc-tool.lin failed, but it skips right over it.
For debugging, I print the grep commands verbatim, and when I copy that line and issue the command in my shell (tcsh), it returns that line...
Shell:
$ grep '\w\w\wccc-.*\.lin failed' /path/to/file.txt
rstccc-tool.lin failed
$ echo $?
0
If grep can find the line when I issue the command normally, how come it won't find it when the bash script is calling grep?
The variable won't be expanded in single quotes. Try with double quotes:
if grep "\w\w\w${pre}-.*\.lin failed" "${status_page}"; then
The ${pre} portion of that script is not parsing it correctly. I believe you need that line to say:
if grep '\w\w\w'${pre}'-.*\.lin failed' ${status_page}; then
... where the ${pre} is outside the quotation, such that bash will do the correct string replacement before sending it to grep.

How to find out name of script called ("sourced") by another script in bash? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
In the bash script how do I know the script file name?
How can you access the base filename of a file you are sourcing in Bash
When using source to call a bash script from another, I'm unable to find out from within that script what the name of the called script is.
file1.sh
#!/bin/bash
echo "from file1: $0"
source file2.sh
file2.sh
#!/bin/bash
echo "from file2: $0"
Running file1.sh
$ ./file1.sh
from file1: ./file1.sh # expected
from file2: ./file1.sh # was expecting ./file2.sh
Q: How can I retrieve file2.sh from file2.sh?
Change file2.sh to:
#!/bin/bash
echo "from file2: ${BASH_SOURCE[0]}"
Note that BASH_SOURCE is an array variable. See the Bash man pages for more information.
if you source a script then you are forcing the script to run in the current process/shell. This means variables in the script from file1.sh you ran are not lost. Since $0 was set to file1.sh it remains as is.
If you want to get the name of file2 then you can do something like this -
file1.sh
#!/bin/bash
echo "from file1: $0"
./file2.sh
file2.sh
#!/bin/bash
echo "from file2: $0"

Resources