cat EOF keeps indenting and interprets variables - linux

use 'EOF',it can keep indenting, but it can't explain variables
[root#master ~]# registry=10.105.100.4/library
[root#master ~]# cat > /etc/sysconfig/kubelet << 'EOF'
> KUBELET_EXTRA_ARGS=--pod-infra-container-image=${registry}/pause:3.1 \
> --runtime-cgroups=/systemd/system.slice --kubelet-cgroups=/systemd/system.slice \
> --feature-gates=LocalStorageCapacityIsolation=true \
> --kube-reserved-cgroup=/kubepods.slice --kube-reserved=cpu=500m,memory=500Mi,ephemeral-storage=1Gi \
> --system-reserved-cgroup=/system.slice --system-reserved=cpu=500m,memory=500Mi,ephemeral-storage=1Gi \
> --eviction-hard=memory.available<500Mi,nodefs.available<10% \
> --max-pods=250
> EOF
[root#master ~]# cat /etc/sysconfig/kubelet
KUBELET_EXTRA_ARGS=--pod-infra-container-image=${registry}/pause:3.1 \
--runtime-cgroups=/systemd/system.slice --kubelet-cgroups=/systemd/system.slice \
--feature-gates=LocalStorageCapacityIsolation=true \
--kube-reserved-cgroup=/kubepods.slice --kube-reserved=cpu=500m,memory=500Mi,ephemeral-storage=1Gi \
--system-reserved-cgroup=/system.slice --system-reserved=cpu=500m,memory=500Mi,ephemeral-storage=1Gi \
--eviction-hard=memory.available<500Mi,nodefs.available<10% \
--max-pods=250
just use EOF,It can interpret variables, but it can't keep indenting,
[root#master ~]# registry=10.105.100.4/library
[root#master ~]# cat > /etc/sysconfig/kubelet << EOF
> KUBELET_EXTRA_ARGS=--pod-infra-container-image=${registry}/pause:3.1 \
> --runtime-cgroups=/systemd/system.slice --kubelet-cgroups=/systemd/system.slice \
> --feature-gates=LocalStorageCapacityIsolation=true \
> --kube-reserved-cgroup=/kubepods.slice --kube-reserved=cpu=500m,memory=500Mi,ephemeral-storage=1Gi \
> --system-reserved-cgroup=/system.slice --system-reserved=cpu=500m,memory=500Mi,ephemeral-storage=1Gi \
> --eviction-hard=memory.available<500Mi,nodefs.available<10% \
> --max-pods=250
> EOF
[root#master ~]# cat /etc/sysconfig/kubelet
KUBELET_EXTRA_ARGS=--pod-infra-container-image=10.105.100.4/library/pause:3.1 --runtime-cgroups=/systemd/system.slice --kubelet-cgroups=/systemd/system.slice --feature-gates=LocalStorageCapacityIsolation=true --kube-reserved-cgroup=/kubepods.slice --kube-reserved=cpu=500m,memory=500Mi,ephemeral-storage=1Gi --system-reserved-cgroup=/system.slice --system-reserved=cpu=500m,memory=500Mi,ephemeral-storage=1Gi --eviction-hard=memory.available<500Mi,nodefs.available<10% --max-pods=250
[root#master ~]#
Is there any way for both to take effect at the same time?

You have to escape the backslashes at the end of the lines (Tested with bash and zsh; I assume other shells are similar):
$ cat > foo.txt <<EOF
line 1 \\
line 2
EOF
$ cat foo.txt
line 1 \
line 2

Related

How to save the response body from cURL in a file when executing the command in a loop in a bash script?

I've created a cURL bash script in which I want to save the response body into a file called output.log, but when I open the file output.log it looks like this:
Here is my bash script:
#!/bin/bash
SECRET_KEY='helloWorld'
FILE_NAME='sma.txt'
function save_log()
{
printf '%s\n' \
"Header Code : $1" \
"Executed at : $(date)" \
"Response Body : $2" \
'==========================================================\n' > output.log
}
while IFS= read -r line;
do
HTTP_RESPONSE=$(curl -I -L -s -w "HTTPSTATUS:%{http_code}\\n" -H "X-Gitlab-Event: Push Hook" -H 'X-Gitlab-Token: '$SECRET_KEY --insecure $line 2>&1)
HTTP_STATUS=$(echo $HTTP_RESPONSE | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
save_log $HTTP_STATUS $HTTP_RESPONSE
done < $FILE_NAME
Can anyone help me get my desired output in my output.log?
From the Curl documentation:
-I, --head Show document info only
Removing the -I or replace it with -i should solve your problem

False reporting on bash script

Context
I have a script that pulls down data from a web server using wget, checks the filesize of the index.html page using ls -la, if it is a certain size using grep -o, it is assumed the page is non-functional to customer requirements.
Code
BADSERVER=()
FILE=SERVER
echo '' > $FILE.txt
<pull a list of hosts down>
if ! ssh -n -f $device -i <sshkey> "yes | rm index.* ; wget localhost:8080 ; ls -la index.html | grep -o 12282" > /tmp/$FILE 2> /dev/null; then
echo "Unable to connect to $device"
BADSERVER+=($device)
echo '' > /tmp/$FILE
elif cat /tmp/$FILE | grep '12282' ; then
echo 'Page is non functional to customer requirements on $device'
BADSERVER+=($device)
echo '' > /tmp/$device
else
echo 'all is fine on $ip'
echo '' > /tmp/$FILE
fi
done
Problem
The script reports that some webservers have the filesize, when manually connecting I can see that the file is not the same size.
Script traceback
+ ssh -n -f webserver.1014 -i <omitted> 'yes | rm index.* ; wget localhost:8080 ; ls -la index.html | grep -o 12282'
+ grep 12282
+ cat /tmp/SERVER.txt
+ echo 'All OK on webserver.1014'
+ echo ''
+ cat /tmp/SERVER.txt
+ cat /tmp/SERVER.txt
+ ssh -n -f webserver.1015 -i <omitted> 'yes | rm index.* ; wget localhost:8080 ; ls -la index.html | grep -o 12282'
+ cat /tmp/SERVER.txt
+ grep 12282
12282
+ echo 'Page is non functional to customer requirements on $device'
Page is non functional to customer requirements on webserver.1015
+ BADSERVER+=($device)
+ echo ''
+ cat /tmp/SERVER.txt
+ cat /tmp/SERVER.txt
+ ssh -n -f webserver.1016 -i <omitted> 'yes | rm index.* ; wget localhost:8080 ; ls -la index.html | grep -o 12282'
+ cat /tmp/SERVER.txt
+ grep 12282
+ echo 'All OK on webserver.1017'
+ echo ''
+ cat /tmp/SERVER.txt
+ cat /tmp/SERVER.txt
Actual content of webserver.1015
-r--r--r--. 1 --- --- 25799 Mar 30 23:38 index.html
Is the server up & running at webserver.1015 ?
Why are you using ; instead of && ?
If previous command failed with ; the second one will run.
But with && the second one will not run.
Don't parse the output of ls command.
Extracting only file size with wget
wget http://localhost:8080/index.html --spider --server-response -O - 2>&1 | sed -ne '/Content-Length/{s/.*: //;p}'
Or with curl
size=$(curl -sI "http://localhost:8080/index.html" | awk '/Content-Length/{gsub("\\r", ""); print $2}')

Import file to script and fill variables inside the file

I have script import.sh
. properties
sql=$(cat sql.sql)
${psql_path}/psql \
-X \
--set ON_ERROR_STOP=on \
--set AUTOCOMMIT=on \
--echo-all \
${sql}
${dbname} > ${log_file} 2>> ${log_file}
and file properties
psql_path="/usr/pgsql-9.6/bin"
dbname="postgres"
path="/opt/files"
log_file="ok.log"
and file sql.sql
-c "truncate table SCHEMA.TABLE1;" \
-c "\\copy SCHEMA.TABLE1 FROM '${path}/TABLE1.tsv' DELIMITER ';' CSV HEADER ENCODING 'UTF8' QUOTE '\"'" \
-c "truncate table SCHEMA.TABLE2;" \
-c "\\copy SCHEMA.TABLE1 FROM '${path}/TABLE2.tsv' DELIMITER ';' CSV HEADER ENCODING 'UTF8' QUOTE '\"'" \
i need to run psql command with importing lines from file sql.sql on the line ${sql} in script import.sh but including text /opt/files instead of the variable itself ${path}, eg:
${psql_path}/psql \
-X \
--set ON_ERROR_STOP=on \
--set AUTOCOMMIT=on \
--echo-all \
-c "truncate table SCHEMA.TABLE1;" \
-c "\\copy SCHEMA.TABLE1 FROM '/opt/files/TABLE1.tsv' DELIMITER ';' CSV HEADER ENCODING 'UTF8' QUOTE '\"'" \
-c "truncate table SCHEMA.TABLE2;" \
-c "\\copy SCHEMA.TABLE2 FROM '/opt/files/TABLE2.tsv' DELIMITER ';' CSV HEADER ENCODING 'UTF8' QUOTE '\"'" \
${dbname} > ${log_file} 2>> ${log_file}
edit: all im getting right now is example below. How do i insert the text of variable ${path} ?
${psql_path}/psql \
-X \
--set ON_ERROR_STOP=on \
--set AUTOCOMMIT=on \
--echo-all \
-c "truncate table SCHEMA.TABLE1;" \
-c "\\copy SCHEMA.TABLE1 FROM '${path}/TABLE1.tsv' DELIMITER ';' CSV HEADER ENCODING 'UTF8' QUOTE '\"'" \
-c "truncate table SCHEMA.TABLE2;" \
-c "\\copy SCHEMA.TABLE2 FROM '${path}/TABLE2.tsv' DELIMITER ';' CSV HEADER ENCODING 'UTF8' QUOTE '\"'" \
${dbname} > ${log_file} 2>> ${log_file}
This line:
sql=$(cat sql.sql)
Will put contents of "sql.sql" into this variable $sql but won't evaluate any variables inside it. The right way to do this is to use a heredoc, instead. But since I figure out you want to keep your script, a simple solution would be:
sql=$(cat sql.sql | sed -e 's#${path}#'"${path}"'#')
This is simple running sed to substitute the contents of "${path}" into the contents of shell variable of the same name. But anyway consider using heredocs, because your "sql" file is obviously not SQL at all.
As advised, the HEREDOC is the best option and then simple parameter substitution can be done:
. properties
sql=$(cat sql.sql)
${psql_path}/psql <<-EOF
-X
--set ON_ERROR_STOP=on
--set AUTOCOMMIT=on
--echo-all
${sql//\$\{path\}/$path}
${dbname} > ${log_file} 2>> ${log_file}
EOF
Notice too that the line extensions are no longer required either. You should be able to remove them from sql.sql file as well

Insert the line with special character (forward slash) in a file in shell script

Script to insert line in file
> cat text
BBLAYERS ?= " \
/home/neeraj/yocto/poky/meta \
/home/neeraj/yocto/poky/meta-yocto \
/home/neeraj/yocto/poky/meta-yocto-bsp \
"
In that I have to insert a line below a pattern as
> cat text
BBLAYERS ?= " \
/home/neeraj/yocto/poky/meta \
/home/neeraj/yocto/poky/meta-yocto \
/home/neeraj/yocto/poky/meta-yocto-bsp \
/home/neeraj/yocto/poky/meta-ti \
"
(Not tested)
Probably what you are looking for:
#!/bin/bash
awk -v search="$1" -v add="$2" '$0 ~ search{$0=$0"\n"add}1' "$3" >$4
exit
Where you would execute with the following format:
user#system:$ ./path-to-script.sh "Line you want to find" "Line you want to add" Input_File Output_File
Let me know if this needs more explanation. :-)

RRDTool GPRINT formatting with printf

Closely related to this question: Bash printf prefix
I have the following Bash script that is generating an RRDGraph with RRDTool.
#!/bin/bash
now=$(date +%s)
now_formatted=$(date +%s | awk '{printf "%s\n", strftime("%c",$1)}' | sed -e 's/:/\\:/g')
# create power graph for last week
/usr/bin/rrdtool graph /var/www/power-week.png \
--start end-7d --width 543 --height 267 --end $now-1min --slope-mode \
--vertical-label "Watts" --lower-limit 0 \
--alt-autoscale-max \
--title "Power: Last week vs. week before" \
--watermark "(©) $(date +%Y) Alyn R. Tiedtke" \
--font WATERMARK:8 \
DEF:Power=/root/currentcost/ccdata.rrd:Power:AVERAGE \
DEF:Power2=/root/currentcost/ccdata.rrd:Power:AVERAGE:end=$now-7d1min:start=end-7d \
VDEF:Last=Power,LAST \
VDEF:First=Power,FIRST \
VDEF:Min=Power,MINIMUM \
VDEF:Peak=Power,MAXIMUM \
VDEF:Average=Power,AVERAGE \
CDEF:kWh=Power,1000,/,168,* \
CDEF:Cost=kWh,.1029,* \
SHIFT:Power2:604800 \
LINE1:Power2#00CF00FF:"Last Week\\n" \
HRULE:Min#58FAF4:"Min " \
GPRINT:Power:MIN:"%6.2lf%sW" \
COMMENT:"\\n" \
LINE1:Power#005199FF:"Power " \
AREA:Power#00519933:"" \
GPRINT:Last:"%6.2lf%sW" \
COMMENT:"\\n" \
HRULE:Average#9595FF:"Average" \
GPRINT:Power:AVERAGE:"%6.2lf%sW" \
COMMENT:"\\n" \
HRULE:Peak#ff0000:"Peak " \
GPRINT:Power:MAX:"%6.2lf%sW" \
COMMENT:"\\n" \
GPRINT:kWh:AVERAGE:" total %6.2lfkWh\\n" \
GPRINT:Cost:AVERAGE:" cost %6.2lf £\\n" \
GPRINT:Cost:AVERAGE:"$(printf \\" cost %11s\\" £%.2lf | sed 's/\£/\£ /g')\\n" \
COMMENT:" \\n" \
GPRINT:First:"Showing from %c\\n":strftime \
GPRINT:Last:" to %c\\n":strftime \
COMMENT:" Created at $now_formatted"
Which produces a graph like this (notice the leading \ on the lower cost line in the legend):-
Concentrating specifically on the following line:-
GPRINT:Cost:AVERAGE:"$(printf \\" cost %11s\\" £%.2lf | sed 's/\£/\£ /g')\\n" \
This is the line that is printing out the lower cost line in the legend.
I am passing a GPRINT formatted value of £4.54 to Bash's printf function to be padded out to 11 spaces and a cost label prefixed on it. I am then piping this to sed to add a space between the £ and the actual value.
What I want to know is, why is the escaped \ coming through in the output? If I remove the \\ just after printf bash complains that something is missing.
How would I suppress this \ from coming through in the output.
Try this line:
GPRINT:Cost:AVERAGE:"$(printf ' cost %11s' £%.2lf | sed 's/\£/\£ /g')\\n" \
I changed the inner " marks to ' marks and removed the backslashes.

Resources