I am using ssh in a shell script in order to go on multiple linux server and get disk information on a particular disk. I am running following but I am not able to figure out the quote sequencing...In this example I am just capturing the header for my report....
ssh dbadmin#myserver bash -c '"df -kh | grep File | awk '{ print \$1 " | " \$2 " | " \$3 " | " \$4 " | " \$5 }' | tail -n -1"'
and following error...
bash: -c: line 0: syntax error near unexpected token |'
bash: -c: line 0:df -kh | grep File | awk { print | | | | } | tail -n -1'
Any help or suggestions would be great...
Thanks
Better to use quoted here-doc and avoid escaping:
ssh -t -t dbadmin#myserver<<'EOF'
df -kh | awk -v OFS=" | " '/file/{ print $1, $2, $3, $4, $5 }' | tail -n -1
EOF
Related
When ran commands locally on the remote server outputs would work as expected:
desired_kernel_version="5.4.0-105-generic"
cat /tmp/grb.bkp | grep GRUB_DEFAULT
GRUB_DEFAULT=0
kernel_position=$(awk -F\' '$1=="menuentry " || $1=="submenu " {print i++ " : " $2}; /\tmenuentry / {print "\t" i-1">"j++ " : " $2};' /boot/grub/grub.cfg | grep "${desired_kernel_version}" | grep -v recovery | awk '{ print $1}' | sed 's/ //g')
echo $k_position
1>2
sed -i "s/GRUB_DEFAULT=0/GRUB_DEFAULT=\"${k_position}\"/g" /tmp/grb.bkp
cat /tmp/grb.bkp | grep GRUB_DEFAULT
GRUB_DEFAULT="1>2"
desired output when ran from remote server:
replace 0 of GRUB_DEFAULT value to kernel_position within quotes.
server=abcd
kernel_position=$(ssh -qT $server awk -F\' '$1=="menuentry " || $1=="submenu " {print i++ " : " $2}; /\tmenuentry / {print "\t" i-1">"j++ " : " $2};' /boot/grub/grub.cfg | grep "${desired_kernel_version}" | grep -v recovery | awk '{ print $1}' | sed 's/ //g')
ssh -qT $server "sed -i "s/GRUB_DEFAULT=0/GRUB_DEFAULT=\"${k_position}\"/g" /tmp/grb.bkp"
Suggesting to avoid quoting hell.
Send muli-line command into ssh by writing a script remote-script.sh with all lines.
remote-script.sh
#!/bin/bash
source ~/.bash_profile
$k_position=$1
desired_kernel_version="5.4.0-105-generic"
cat /tmp/grb.bkp | grep GRUB_DEFAULT
GRUB_DEFAULT=0
kernel_position=$(awk -F\' '$1=="menuentry " || $1=="submenu " {print i++ " : " $2}; /\tmenuentry / {print "\t" i-1">"j++ " : " $2};' /boot/grub/grub.cfg | grep "${desired_kernel_version}" | grep -v recovery | awk '{ print $1}' | sed 's/ //g')
echo $k_position
1>2
sed -i "s/GRUB_DEFAULT=0/GRUB_DEFAULT=\"${k_position}\"/g" /tmp/grb.bkp
cat /tmp/grb.bkp | grep GRUB_DEFAULT
GRUB_DEFAULT="1>2"
Give current user execution permissions on remote-script.sh
chmod u+x remote-script.sh
Use scp command to copy remote-script.sh to $server. If possible only once at deploy time.
scp -q remote-script.sh $server:/home/your-user
Use ssh command to run remote-script.sh on remote server. Pass $k_position in command line.
ssh -qT $server "bash -c /home/your-user/remote-script.sh $k_position"
BTW, in computing kernel_position, suggesting to fold all awk, grep, sed commands into a single awk script.
Help please
Here i have a part of Jenkinsfile like
#Library('groovy_shared_libraries')_
stage("Ensure droplet don`t exist and Create DO Droplet") {
// Ensure droplet don`t exist
ExistDroplet = sh(
script: "doctl compute droplet list | awk '{gsub(/\./, "", $2)} 1' | grep -w $(echo $FullDomainName | sed "s/\.//g") | awk '{ print $2 }' | wc -l"
returnStdout: true
).trim()
How i can execute this bash command in jenkinsfile groovy?
doctl compute droplet list | awk '{gsub(/\./, "", $2)} 1' | grep -w $(echo $FullDomainName | sed "s/\.//g") | awk '{ print $2 }' | wc -l
With the current implementation, it returns an error
WorkflowScript: 26: unexpected char: '\' # line 26, column 63.
te droplet list | awk '{gsub(/\./, "", $
if i add additional \ to command i have this error
WorkflowScript: 26: illegal string body character after dollar sign;
solution: either escape a literal dollar sign "\$5" or bracket the value expression "${5}" # line 26, column 21.
script: `"doctl compute droplet list | awk '{gsub(/\\./, "", $2)} 1' | grep -w $(echo $FullDomainName | sed "s/\\.//g") | awk '{ print $2 }' | wc -l",`
after adding escape $2 jenkins show this error
WorkflowScript: 26: illegal string body character after dollar sign;
solution: either escape a literal dollar sign "\$5" or bracket the value expression "${5}" # line 26, column 21.
script: `"doctl compute droplet list | awk '{gsub(/\\./, "", \$2)} 1' | grep -w $(echo $FullDomainName | sed "s/\\.//g") | awk '{ print \$2 }' | wc -l",`
This all works with this command doctl compute droplet list | grep -w \"$FullDomainName\" | awk '{ print \$2 }' | wc -l
but i need to add
awk '{gsub(/\\./, "", $2)} 1' | grep -w $(echo $FullDomainName | sed "s/\\.//g")
\ is the escape character for the shell and Jenkins. If you want to send the backslash character to the shell you need to escape it with another one for Jenkins like so (notice the \\):
script: "doctl compute droplet list | awk '{gsub(/\\./, "", $2)} 1' | grep -w $(echo $FullDomainName | sed "s/\\.//g") | awk '{ print $2 }' | wc -l"
I am running below script:-
#!/bin/bash
threshold="20"
i=2
result=`df -kh |grep -v “Filesystem” | awk ‘{ print $5 }’ | sed ‘s/%//g’`
for percent in $result; do
if ((percent > threshold))
then
partition=`df -kh | head -$i | tail -1| awk ‘{print $1}’`
echo “$partition at $(hostname -f) is ${percent}% full”
fi
let i=$i+1
done
But I get the following error:
awk: ‘{
awk: ^ invalid char '▒' in expression
sed: -e expression #1, char 1: unknown command: `▒'
Please help me to resolve this.
What awk does not work? (your script does work fine on my Ubuntu)
This line:
result=`df -kh |grep -v "Filesystem" | awk '{ print $5 }' | sed 's/%//g'`
could be changed to:
result=$(df -kh | awk '!/Filesystem/ {print $5+0}')
Avoid using old and outdated backtics if parentheses works like this: var=$(code...)
This:
partition=`df -kh | head -$i | tail -1| awk '{print $1}'`
could be changed to:
partition=$(df -kh | awk -v line="$i" 'NR==line {print $1}')
This
let i=$i+1
could be change to:
((i++))
This would then give some like this:
#!/bin/bash
threshold="20"
i=2
result=$(df -kh | awk '!/Filesystem/ {print $5+0}')
for percent in $result; do
if ((percent > threshold))
then
partition=$(df -kh | awk -v line="$i" 'NR==line {print $1}')
echo "$partition at $(hostname -f) is ${percent}% full"
fi
((i++))
done
You're using ‘ for a single quote not '. Try re-encoding your file with an editor.
You got the answer to your syntax error, now re-write the whole script as just:
#!/bin/bash
df -kh |
awk -v t=20 -v h="$(hostname -f)" '(NR>1)&&($5+0>t){printf "%s at %s is %s full\n",$1,h,$5}'
TMPFILE=/tmp/jboss_ps.$$
${PS} ${PS_OPTS} | \
grep ${JBOSS_HOME}/java | \
egrep -v " grep | \
tee | $0 " | ${AWK} '{print $NF " "}' | \
sort -u > ${TMPFILE} 2>/dev/null
I want to know what this precise line is doing from the code above
egrep -v " grep | \
tee | $0 "
At first i thought that that line is searching for everything that does not contain this exact string "grep | \ tee | $0" but it appears that egrep is processing the pipes, so what's the significance of the pipes here, does it mean OR ? From my test it appears that it's not, but if it means output redirection then what's the inner grep getting ? And why is tee alone too ?
AFAIK
egrep -v " grep | \
tee | $0 "
is nothing but
egrep -v " grep | tee | $0 "
where \ is the continuation character in bash.
egrep is same as grep -E
-v for inverted selection
tee just another string
so egrep -v " grep | tee | $0 " does find lines that have the string {java path} and within this results, all the lines that doesn't match the condition {either of grep OR tee OR $0 } where
$0 is the filename not a '$0' because it uses DOUBLE QUOTES and not single quotes :)
" commands | $variables " has the tendency to expand the variables and use the utility.
The commands in the pipeline before the egrep command is probably something like
ps -ef|grep .... The egrep -v (Option)line you asked about is simply omitting lines you
don't want in the results, in this case the initial grep command issued by the
script, any tee commands and lastly $0 which is the name of the this script
being executed. egrep allows to enter multiple patterns enclosed in double quotes and
separated by pipe symbol. Syntax egrep -[option or not] "patern1|patern2|patern..."
grep -A 26 "some text" somefile.txt |
awk '/other text/ { gsub(/M/, " "); print $4 }' |
sort -n -r | uniq | head -1
will return the largest in a list pulled from a large text file, but how do I store the output as a variable?
Use command substitution:
my_var=$(grep -A 26 "some text" somefile.txt |
awk '/other text/ { gsub(/M/, " "); print $4 }' |
sort -n -r | uniq | head -n1)
Also, for portability, I would suggest always using -n1 for the argument of head. I've come across a couple of incarnations of it where using -1 doesn't work.
For unnested cases back quotes will work too:
variable=`grep -A 26 "some text" somefile.txt |
awk '/other text/ { gsub(/M/, " "); print $4 }' |
sort -nru | head -1`
I'd suggest
variable_name=$(grep -A 26 "some text" somefile.txt |
awk '/other text/ { gsub(/M/, " "); print $4 }' |
sort -nru | head -1)