Bash create file script with echo command [duplicate] - bash

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"

Related

Execute bash within some text file [duplicate]

This question already has answers here:
Forcing bash to expand variables in a string loaded from a file
(13 answers)
Closed 1 year ago.
I would like to create a templating system that executes bash within a text file.
For example, let's consider we created a simple template.yaml file:
my_path: $(echo ${PATH})
my_ip: $(curl -s http://whatismyip.akamai.com/)
some_const: "foo bar"
some_val: $(echo -n $MY_VAR | base64)
The desire is to execute each one, such that the result may look like:
my_path: /Users/roman/foo
my_ip: 1.2.3.4
some_const: "foo bar"
some_val: ABC
How would I go about doing such a substitution?
Reasons for wanting this:
There are many values, and doing something like a sed or envsubst isn't practical
It would be common to apply a series of piped transformations
The configuration file would be populated from numerous sources, all of them essentially bash commands
I do need to create a yaml file of a specific format (ultimately used by another tool)
I could create aliases etc to increase readability
By having it execute in it's own shell none of the semi-sensitive values are stored as in history or as files.
I'm not married to this approach, and would happily attempt a recommendation that fulfils the reasons.
This might work, you can try though:
you can create a script: script.sh which will take one argument as .yaml file and will expand the variables inside that file:
script.sh :
echo 'cat <<EOF' > temp.sh
cat "$1" >> temp.sh
echo 'EOF' >> temp.sh
bash temp.sh
rm temp.sh
and you can invoke the script as from the command line : ./script.sh template.yaml
Thank you to #joshmeranda for pointing me in the right direction, this solved my problem
echo -e "$(eval "echo -e \"`<template.yaml`\"")"
While eval can be dangerous, in my case its usage is controlled.

Why the loop runs only 1 time instead of reaching the end of the file? [duplicate]

This question already has answers here:
Bash exec in infinite while loop doesn't work
(2 answers)
Closed 1 year ago.
I am needing to read the file "namespace.txt" and execute "exec" for each line that the file contains, but only the first line of the txt is executed :(
Txt file:
ocp_namespace_1
...
ocp_namespace_n
Bash file:
while IFS="" read -r p || [ -n "$p" ]
do
echo ${p}
exec velero schedule create ${p} --schedule="#every 6h" --include-namespaces ${p} --ttl 240h0m0s
done < namespaces.txt
Any sugestions?
because exec replaces the script with the executed command; from man exec:
The exec() family of functions replaces the current process image with a new process image.
and the bash builtin exec is an interface to this:
Execute COMMAND, replacing this shell with the specified program.
Blockquote
So it never returns to complete the loop. As other commenters have suggested, simply remove the word exec.

Replance extension for shell script error

I am trying to write shell script (sh), Where I am getting below error
variable i contains:
test.txt
code:
echo "${i/.txt/}"
Error:
just.sh: 16: just.sh: Bad substitution
expected output string :
text
Reproduce steps
Create file:
touch text.txt
Create file test.sh contents using any of editor
code:
#!/bin/sh
for i in `find *.txt`
do
echo "$i"
echo "${i/.txt/}"
done
How to run:
sh test.sh
sh is not bash. Fix your shebang (the 1st line) as #!/bin/bash first.
References
Difference between sh and bash, search "expansion" in the thread
Bash features a rich set of expanded non-standard parameter expansions such as ${substring:1:2}, ${variable/pattern/replacement}, case conversion, etc.

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

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.

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