What does the colon dash ":-" mean in bash [duplicate] - bash

This question already has answers here:
Usage of :- (colon dash) in bash
(2 answers)
Closed 8 years ago.
The result is the one desired; after a bit of trial and error. I don't understand what the "2:-" and "3:-" do/mean. Can someone explain.
#!/bin/bash
pid=$(ps -ef | grep java | awk ' NR ==1 {print $2}')
count=${2:-30} # defaults to 30 times
delay=${3:-10} # defaults to 10 second
mkdir $(date +"%y%m%d")
folder=$(date +"%y%m%d")
while [ $count -gt 0 ]
do
jstack $pid >./"$folder"/jstack.$(date +%H%M%S.%N)
sleep $delay
let count--
echo -n "."
done

It's a parameter expansion, it means if the third argument is null or unset, replace it with what's after :-
$ x=
$ echo ${x:-1}
1
$ echo $x
$
There's also another similar PE that assign the value if the variable is null:
$ x=
$ echo ${x:=1}
1
$ echo $x
1
Check http://wiki.bash-hackers.org/syntax/pe

Related

`echo` is stripping newlines in Bash script [duplicate]

This question already has answers here:
I just assigned a variable, but echo $variable shows something else
(7 answers)
When should I double-quote a parameter expansion? [duplicate]
(1 answer)
Closed 5 months ago.
If I have a file containing newlines, the below script will output the file as is, with newlines:
#!/bin/bash
FOO=$(cat filename.yaml)
echo "$FOO"
but
#!/bin/bash
FOO=$(cat filename.yaml)
FOO=$(echo $FOO)
echo "$FOO"
outputs the file all on one line. How come?
I do not recommend storing the contents of entire files in a single variable. In my experience that can have unpredictable results.
/usr/bin/env bash -x
index=$(wc -l filename.yaml | cut -d' ' -f1)
count=1
next () {
[[ "${count}" -lt "${index}" ]] && main
[[ "${count}" -eq "${index}" ]] && exit 0
}
main () {
line=$(sed -n "${count}p" filename.yaml)
echo "var${count}=${line}" >> varfile
count=$(($count+1))
next
}
next
If you source varfile at the start of another script, it will give you every line from that file, in its' own variable.

Simple bash script output [duplicate]

This question already has answers here:
Why should there be spaces around '[' and ']' in Bash?
(5 answers)
Closed 9 months ago.
I try to write simple script to read temperature:
cpu=$(cat /sys/class/thermal/thermal_zone*/temp)
if [$cpu -ge 50000]; then
echo "OK"
else
echo "Not OK"
fi
echo $cpu is fine: 64000 but script output is:
myscript.sh: 2: [64000: not found
Not OK
What is wrong with line 2?
Thank You.
You want to make a few changes here:
Add a space between the [ and the $cpu, and before the ] (as per the comments above)
Place the $cpu into double quotes, to avoid unexpected results
Handle the possibility of maximum values, by picking up the maximum (or minimum, or average).
cpu="$(cat /sys/class/thermal/thermal_zone*/temp | sort -nr | head -1)"
if [ "$cpu" -ge 50000 ] ; then
echo "OK"
else
echo "NOT"
fi
If you prefer the space-less expressions, you can use the arithmetic expressions
cpu="$(cat /sys/class/thermal/thermal_zone*/temp | sort -nr | head -1)"
if ((cpu>50000)) ; then
echo "OK"
else
echo "NOT"
fi

Bash script to add absolute values of numbers seperated by spaces

I need a bash script to find the sum of the absolute value of integers separated by spaces. For instance, if the input is:
1 2 -3
the script should print 6 to standard output
I have:
while read x ; do echo $(( ${x// /+} )) ; done
which gives me
0
Without over complicated things, how would I include an absolute value of each x in that statement so the output would be:
6
With Barmar's idea:
echo "1 2 -3" | tr -d - | tr ' ' '+' | bc -l
Output:
6
You have almost done it, but the -s must have been removed from the line read:
while read x; do x=${x//-}; echo $(( ${x// /+} )); done
POSIX friendly implementation without running a loop and without spawning a sub-shell:
#!/usr/bin/env sh
abssum() {
IFS='-'
set -- $*
IFS=' '
set -- $*
IFS=+
printf %d\\n $(($*))
}
abssum 1 2 -3
Result:
6

Bash - how to set variable within an if [] condition and use outside [duplicate]

This question already has answers here:
'&&' vs. '&' with the 'test' command in Bash
(3 answers)
Assign variable in the background shell
(2 answers)
Closed 2 years ago.
I'm trying to get my head around this. I have a basic Bash script:
#!/bin/bash
do_exit=0
while [ "$do_exit" == 0 ] ; do
echo $do_exit
do_exit=1
done
This works. However, when I want to set do_exit=1 inside an if condition:
#!/bin/bash
do_exit=0
while [ "$do_exit" == 0 ] ; do
free=`free -m | grep Mem | awk '{print $4}'`
if [ "$free" -gt 0 ]
then
echo $do_exit
do_exit=1
fi & sleep 5;
done
$do_exit is ALWAYS 0 ... so never exists. What am I doing wrong? I'm have the same issue with "breaking" and "exit 0" when I want to kill te script - it just carries on!)
I must be misunderstanding how variables work in Bash? In Perl (my normal programing language), you can set variables anywhere (with the exception of explicitly setting them in a function)
There are a couple of errors.
you echo do_exit before you set it to 1
you have fi & sleep 5; which makes the if statement a child process, thus you can't use the value in the parent process
-gt is for numeric comparisment, not strings.
Below should work for you.
#!/bin/bash
do_exit=0
while [ "$do_exit" == 0 ] ; do
free=`free -m | grep Mem | awk '{print $4}'`
if [[ $free -gt 0 ]]; then
do_exit=1
echo ${$do_exit}
fi
sleep 5;
done
You can break while loops as well. Check this:
#!/bin/bash
while true; do
free=$(free -m | grep Mem | awk '{print $4}')
if [[ $free -gt 0 ]]; then
break;
fi
sleep 5;
done

`echo " $1 % 2" | bc -l` doesn't work in the terminal or bash script but `bc` takes these arguments within `bc` [duplicate]

This question already has answers here:
bash, bc modulo does not work with -l flag
(5 answers)
How do I check whether a variable has an even numeric value?
(3 answers)
Closed 4 years ago.
I haven't been able to find anything related to this nor can my professor explain what's going on. Below is the problem description:
After quite a bit of debugging following is the bash script to print odd or even:
echo $1
odd_even=$(echo "$1 % 2" | bc -l)
echo $odd_even
if [[ $odd_even -eq 0 ]]
then
echo "even"
else
echo "odd"
fi
Following is the output:
$ bash logic_ex2.sh 3
3
0
even
This is weird because the variable odd_even contains 0 while the argument is 3.
We ran the following command to check whats wrong with the echo "3 % 2" | bc -l construction since without using that construction we could get the script working:
$ echo "3 % 2" | bc -l
0
Then we ran bc in the terminal and ran 3 % 2 which gave 1 as the proper output.
Can somebody please explain what is happening here?
Check this explanation as to bc -l calculates a % b differently from plain bc without the -l. The quick solution is to set your scale back to zero:
$ bc -l <<< "scale=0; 3 % 2"
1
But I would probably do this without using bc at all, since bash includes sufficient functionality to calculate integer remainders. If all you need is integer math, bash may be good enough on its own.
#!/usr/bin/env bash
echo "$1"
odd_even=$(($1 % 2))
echo "$odd_even"
if [[ $odd_even -eq 0 ]]; then
echo "even"
else
echo "odd"
fi
My results:
$ bash remtest.sh 3
3
1
odd
$ bash remtest.sh 4
4
0
even
another option:
#!/bin/bash
var=$1
if [[ $((var % 2)) -eq 0 ]];
then echo "$var is even";
else echo "$var is odd";
fi

Resources