Use echo to concatenate two strings to pipe to another command - bash

I'm trying to use this command to do different things based on the version of tmux installed.
But since the version is a float, I can't use normal bash checking, so I'm trying to use bc which takes in arguments in the form of "a
[[ echo `tmux -V | cut -d ' ' -f2` "> 1.6" | bc ]]
But if I do that, I get
-bash: conditional binary operator expected
-bash: syntax error near `-f2`>'
The first part tmux -V | cut -d ' ' -f2\ returns something like 1.6 or 1.8, so I'm trying to concatenate that with "> 1.6" to get an expression like "1.8> 1.6".
So I'm not really sure how to do this.
This is also going in a .tmux.conf file, and so I don't think I'd be able to store the result of the first part in another variable first.

You should not have an \ in the cut command. This works
echo "$(tmux -V | cut -d ' ' -f2) >1.6" | bc
Also, you may try this:
echo "$(tmux -V | awk '{print $2}') >1.6" | bc
And the test should be comparing to 1:
if [[ "$(echo "$(tmux -V | awk '{print $2}') >1.6" | bc)" -eq 1 ]]; then
echo "version above 1.6"
else
echo "please update your version"
fi
Please understand that doing a "floating point" test means that 1.11 is smaller than 1.6.
Not what is intended, I believe.
The correct test will need to split the version string on the dot and comparing both numeric (integer) values:
#!/bin/bash
IFS=' .' read _ one two <<< "$( tmux -V )"
if (( ( one == 1 && two > 6 ) || one > 1 )); then
echo "version above 1.6 present"
else
echo "please update tmux to a version higher than 1.6"
fi

Related

command not found on shell script run [duplicate]

This question already has answers here:
bash command not found when setting a variable
(2 answers)
Closed 6 months ago.
i have a script that compare heapmemory
#!/bin/bash
$a=$(jcmd `jps -l | grep com.adobe.coldfusion.bootstrap.Bootstrap | cut -f1 -d ' '` GC.heap_info | awk 'NR==2 {print $5}')
$b=1000000K
if [[ $a -ge $b ]]
then
echo "The heapmemory used is greater."
else
echo "The heapmemory used is small."
fi
my question is when I am executing this script using ./testscriptforheap.sh, although the output is correct but why I am getting this command not found in line number 2 and 3 I am not able to figure it out.
> ./testscriptforheap.sh: line 2: =1603644K: command not found
> ./testscriptforheap.sh: line 3: =1000000K: command not found
The heapmemory used is greater.
Assignments in bash (and also in sh) don't use the $ in front of them:
a=$(jcmd `jps -l | grep com.adobe.coldfusion.bootstrap.Bootstrap | cut -f1 -d ' '` GC.heap_info | awk 'NR==2 {print $5}')
b=1000000K
Your variable assignment is incorrect, try this:
#!/bin/bash
a=$(jcmd "$(jps -l | grep com.adobe.coldfusion.bootstrap.Bootstrap | cut -f1 -d ' ')" GC.heap_info | awk 'NR==2 {print $5}')
b=1000000K
if [[ $a -ge $b ]]
then
echo "The heapmemory used is greater."
else
echo "The heapmemory used is small."
fi
...also, the bash -gt operator is trying to compare two integers.
From what I can gather:
When you issue the jcmd nnnn GC.heap_info command, it's the sixth field of the second record in the output holds the used heap memory.
It will be of this form nnnnnK, so to be able to compare just the numbers, you could do with piping that through a sed:
Then you could remove K from $b=1000000K.
So, no harm in trying...
#!/bin/bash
a=$( \
jcmd `jps -l | grep com.adobe.coldfusion.bootstrap.Bootstrap | cut -f1 -d ' '` GC.heap_info | awk 'NR==2 {print $6}' | sed -r 's/[^0-9]//g' \
)
b=1000000
if [[ $a -ge $b ]]
then
echo "The heapmemory used is greater."
else
echo "The heapmemory used is small."
fi

How to cut variables which are beteween quotes from a string

I had problem with cut variables from string in " quotes. I have some scripts to write for my sys classes, I had a problem with a script in which I had to read input from the user in the form of (a="var1", b="var2")
I tried the code below
#!/bin/bash
read input
a=$($input | cut -d '"' -f3)
echo $a
it returns me a error "not found a command" on line 3 I tried to double brackets like
a=$(($input | cut -d '"' -f3)
but it's still wrong.
In a comment the OP gave a working answer (should post it as an answer):
#!/bin/bash
read input
a=$(echo $input | cut -d '"' -f2)
b=$(echo $input | cut -d '"' -f4)
echo sum: $(( a + b))
echo difference: $(( a - b))
This will work for user input that is exactly like a="8", b="5".
Never trust input.
You might want to add the check
if [[ ${input} =~ ^[a-z]+=\"[0-9]+\",\ [a-z]+=\"[0-9]+\"$ ]]; then
echo "Use your code"
else
echo "Incorrect input"
fi
And when you add a check, you might want to execute the input (after replacing the comma with a semicolon).
input='testa="8", testb="5"'
if [[ ${input} =~ ^[a-z]+=\"[0-9]+\",\ [a-z]+=\"[0-9]+\"$ ]];
then
eval $(tr "," ";" <<< ${input})
set | grep -E "^test[ab]="
else
echo no
fi
EDIT:
#PesaThe commented correctly about BASH_REMATCH:
When you use bash and a test on the input you can use
if [[ ${input} =~ ^[a-z]+=\"([0-9]+)\",\ [a-z]+=\"([0-9])+\"$ ]];
then
a="${BASH_REMATCH[1]}"
b="${BASH_REMATCH[2]}"
fi
To extract the digit 1 from a string "var1" you would use a Bash substring replacement most likely:
$ s="var1"
$ echo "${s//[^0-9]/}"
1
Or,
$ a="${s//[^0-9]/}"
$ echo "$a"
1
This works by replacing any non digits in a string with nothing. Which works in your example with a single number field in the string but may not be what you need if you have multiple number fields:
$ s2="1 and a 2 and 3"
$ echo "${s2//[^0-9]/}"
123
In this case, you would use sed or grep awk or a Bash regex to capture the individual number fields and keep them distinct:
$ echo "$s2" | grep -o -E '[[:digit:]]+'
1
2
3

get rid of integer expression expected in script

I know this has been asked many times here, but I have looked through all of the previous ones and still can't resolve it. This is just a simple script that checks for a running service and takes the action I define.
#!/bin/bash
SERVICE="$1"
RESULT=`ps -a | sed -n /${SERVICE}/p`
MEM=$(ps aux | sort -rk +4 | grep $1 | grep -v grep | awk '{print $4}' | awk 'NR == 1')
if [ "${RESULT:-null}" = null ]; then
echo "$1 is NOT running"
else
echo "$MEM"
fi
if [ "$MEM" -ge 1 ]; then
mailx -s "Alert: server needs to be checked" me#admins.com
fi
This is the error I get:
./check_service: line 15: [: 5.4: integer expression expected
If I take out the command for the MEM variable and run it outside the script it returns 5.4, which is what I would expect. In my script I have tried changing the "1" to a "1.0" since the output would always be in decimal format, but that did not help. I feel like I am missing something simple here.
Error is due to the fact that bash only supports integer mathematics and your script is comparing 5.4 with 1.
You can fix your script by using:
if [[ ${MEM%.*} -ge 1 ]]l then
mailx -s "Alert: server needs to be checked" me#admins.com
fi
${MEM%.*} will strip part after decimal point and since you're just comparing it with 1 there is no need to have decimal point in variable MEM.

bash: sed: unexpected behavior: displays everything

I wrote what I thought was a quick script I could run on a bunch of machines. Instead it print what looks like might be directory contents in a recursive search:
version=$(mysql Varnish -B --skip-column-names -e "SELECT value FROM sys_param WHERE param='PatchLevel'" | sed -n 's/^.*\([0-9]\.[0-9]*\).*$/\1/p')
if [[ $(echo "if($version == 6.10) { print 1; } else { print 0; }" | bc) -eq 1 ]]; then
status=$(dpkg-query -l | awk '{print $2}' | grep 'sg-status-polling');
cons=$(dpkg-query -l | awk '{print $2}' | grep 'sg-consolidated-poller');
if [[ "$status" != "" && "$cons" != "" ]]; then
echo "about to change /var/www/Varnish/lib/Extra/SG/ObjectPoller2.pm"; echo;
cp /var/www/Varnish/lib/Extra/SG/ObjectPoller2.pm /var/www/Varnish/lib/Extra/SG/ObjectPoller2.pm.bkup;
sed -ir '184s!\x91\x93!\x91\x27--timeout=35\x27\x93!' /var/www/Varnish/lib/Extra/SG/ObjectPoller2.pm;
sed -n 183,185p /var/www/Varnish/lib/Extra/SG/ObjectPoller2.pm; echo;
else
echo "packages not found. Assumed to be not applicable";
fi
else
echo "This is 4.$version, skipping";
fi
The script is supposed to make sure Varnish is version 4.6.10 and has 2 custom .deb packages installed (not through apt-get). then makes a backup and edits a single line in a perl module from [] to ['--timeout=35']
it looks like its tripping up on the sed replace one liner.
There are two major problems (minor ones addressed in comments). The first is that you use the decimal code for [] instead of the hexa, so you should use \x5b\x5d instead of \x91\x93. The second problem is that if you do use the proper codes, sed will still interpret those syntactically as []. So you can't escape escaping. Here's what you should call:
sed -ri'.bkup' '184s!\[\]![\x27--timeout=35\x27]!' /var/www/Varnish/lib/Extra/SG/ObjectPoller2.pm
And this will create the backup for you (but you should double check).

bash: Grab fields 5 and 7 from a Unix path?

Given paths like this:
/data/mirrors/third-party/centos/5/projectA/x86_64
/data/mirrors/third-party/centos/5/projectA/i386
/data/mirrors/third-party/centos/5/projectA/noarch
/data/mirrors/third-party/centos/4/projectB/x86_64
/data/mirrors/third-party/centos/4/projectB/i386
/data/mirrors/third-party/centos/4/projectB/noarch
/data/mirrors/third-party/centos/4/projectC/x86_64
/data/mirrors/third-party/centos/4/projectC/i386
/data/mirrors/third-party/centos/4/projectC/noarch
How can I grab the values from field 5 and 7 ('5' and 'x86_64') using Bash shell commands?
I have something like this so far, but I'm looking for something more elegant, and without the need to capture the 'junk*':
cd /data/mirrors/third-party/centos/5/project/x86_64
echo `pwd` | tr '/' ' ' | while read junk1 junk2 junk3 junk4 version junk5 arch; do
echo version=$version arch=$arch
done
version=5 arch=x86_64
This works for me:
pwd | awk -F'/' '{print "version=" $6 " arch=" $8}'
You can use IFS and an array to split the directory into its components:
#!/bin/bash
saveIFS=$IFS
IFS='/'
dirs=($(pwd))
IFS=$saveIFS
version=${dirs[5]}
arch=${dirs[7]}
> p=$(pwd)
> echo $p
/data/mirrors/third-party/centos/5/projectA/x86_64
> basename ${p}
x86_64
> basename ${p%/*/*}
5
You can also use something like:
echo `expr match "$p" '<regular-expression>'`
...perhaps someone might help me with that regular expression ;)
try this
echo `pwd` | cut -d'/' -f6,8 | tr '/' ' '
to display field
or to display with sring version and arch
echo `pwd` | cut -d'/' -f6,8 | sed -e 's/\(.*\)\/\(.*\)/version=\1 arch=\2/'

Resources