why this do not work:
if [ $_TYPE == 1 ] || [ $_TYPE == 2 ]; then
$_TYPE=$(echo "Outbound");
fi
or
if [ $_TYPE == 1 ] || [ $_TYPE == 2 ]; then
$_TYPE=echo "Outbound";
fi
or
if [ $_TYPE == 1 ] || [ $_TYPE == 2 ]; then
$_TYPE="Outbound";
fi
I'm receiving this error: line 251: 2=Outbound: command not found
In POSIX shells such as Bash, $ is not part of the variable-name, it's just the notation for expanding the variable (to obtain its value); so, for example, echo "$_TYPE" prints the value of the variable _TYPE. You don't use the $ when you're assigning to the variable. So you just need:
if [[ "$_TYPE" = 1 || "$_TYPE" = 2 ]] ; then
_TYPE=Outbound
fi
$ is used to access the value, but if you have to assign a value, the syntax is :
_TYPE="newValue"
Related
(Apologies in advance if my english is bad)
So, I have started studying bash, and want to make a Connect 4 game in it.
However, I got stuck a bit. I have 7 arrays named column0 to column6, and I want to reference them later on.
I read in another post a few days ago, that i can use nameref to do so, but I think I'm doing something wrong, as the function runs, but doesn't do anything (doesn't check for winner). Here is a snippet form the code
declare -n nr="column$j"
for ((j=0 ; j < 6; j++ )); do
if [ "${nr[0]}" = $k ] && [ "${nr[1]}" = $k ] && [ "${nr[2]}" = $k ] && [ "${nr[3]}" = $k ]; then
(this is part of the function that will check for a winner, in case 4 characters in a row match. 'k' is just a color variable, it can be $k='Y' or $k='R')
Could someone point out what I'm doing wrong here? Or am I just dumb and Bash can't work with such solutions?
Thank you in advance for any help.
Given your specifications I tried to reproduce a minimal example.
You can try to do something like this:
#!/usr/bin/env bash
k="Y"
nr_0=("R" "R" "Y" "Y")
nr_1=("R" "Y" "Y" "Y")
nr_2=("Y" "R" "Y" "Y")
nr_3=("Y" "Y" "R" "Y")
nr_4=("Y" "Y" "Y" "R")
nr_5=("Y" "Y" "Y" "Y") # the winner
nr_6=("Y" "R" "Y" "Y")
for j in {0..6}; do
tmp_array_name="nr_$j[#]"
tmp_array=("${!tmp_array_name}")
if [ "${tmp_array[0]}" == "$k" ] && [ "${tmp_array[1]}" == "$k" ] && [ "${tmp_array[2]}" == "$k" ] && [ "${tmp_array[3]}" == "$k" ]; then
echo "The winner is $tmp_array_name - ${tmp_array[*]}"
fi
done
With this output:
The winner is nr_5[#] - Y Y Y Y
You need the nameref declare assignment to be within your loop or it gets assigned an empty string:
for ((j=0 ; j < 6; j++ )); do
declare -n nr="column$j"
if [ "${nr[0]}" = $k ] && [ "${nr[1]}" = $k ] && [ "${nr[2]}" = $k ] && [ "${nr[3]}" = $k ]; then
Another option to nameref which is as risky as the dynamic naming ${!dyn_name_var}, is to use Bash's associative arrays:
declare -A grid=()
for ((column=0 ; j < 6; column++ )); do
if [ "${grid[$column,0]}" == "$k" ] &&
[ "${grid[$column,1]}" == "$k" ] &&
[ "${grid[$column,2]}" == "$k" ] &&
[ "${grid[$column,3]}" == "$k" ]
then
: ...
fi
: ...
done
This will use an associative arrays of key formed by column,line.
Example of the first two lines of the grid associative array as declared statically.
declare -A grid=(
[0,0]="o" [0,1]="x" [0,2]=" ", [0,3]="o"
[1,0]=" " [1,1]="o" [1,2]="x", [1,3]="o"
)
See: How to declare 2D array in bash
I am running the following script, which has a function intended to tell me whether one date is before another, as seen at the very bottom of the script.
Now, the script has a few bugs. But one of them in particular is strange. The script creates files named by the dates that are inputted by the last argument.
It creates files called "09", "12", and "2015". Why are these files created? Here's the function. You'll notice the last few lines which call the function with inputs
function compare_two {
if [ $1 < $2 ];
then
return 2
elif [ $1 > $2 ];
then
return 3
else
return 4
fi
}
function compare_dates {
# two input arguments:
# e.g. 2015-09-17 2011-9-18
date1=$1
date2=$2
IFS="-"
test=( $date1 )
Y1=${test[0]}
M1=${test[1]}
D1=${test[2]}
test=( $date2 )
Y2=${test[0]}
M2=${test[1]}
D2=${test[2]}
compare_two $Y1 $Y2
if [ $? == 2 ];
then
echo "returning 2"
return 2
elif [ $? == 3 ];
then
return 3
else
compare_two $M1 $M2;
if [ $? == 2 ];
then
echo "returning 2"
return 2
elif [ $? == 3 ];
then
return 3
else
compare_two $D1 $D2;
if [ $? == 2 ];
then
echo $?
echo "return 2"
return 2
elif [ $? == 3 ];
then
echo "returning 3"
return 3
else
return 4
fi
fi
fi
}
compare_dates 2015-09-17 2015-09-12
echo $?
the result doesn't throw an error, but rather outputs
returning 2
2
The result is incorrect, I'm aware. But I'll fix that later. What is creating these files and how do I stop it? Thanks.
the lower and greater sign are interpreted as redirections.
type man test and find out the right syntax
Your problem is with the [ $1 < $2 ], the < is being understood as a redirection character.
The solution is to use any of this alternatives:
[ $1 \< $2 ]
[ $1 -lt $2 ]
(( $1 < $2 )) # works in bash.
The [[ $1 < $2 ]] is NOT an integer compare, but (from the manual):
« the < and > operators sort lexicographically using the current locale »
I'll recommend to use the (( $1 < $2 )) option.
to avoid a problem that some numbers (the ones that start with a zero) like 08 cause a problem when compared in an arithmetic expansion, use:
(( 10#$1 < 10#$2 ))
(( 10#$1 > 10#$2 ))
to force a base 10 for the numbers.
However, if possible, using GNU date is a lot easier IMhO (it transform Year/Month/Day into one single number to compare: seconds since epoch):
a=$(date -d '2015-09-17' '+%s');
b=$(date -d '2015-09-12' '+%s');
compare_two "$a" "$b"
Quick question regrading if/else statements in shell, Right now I am trying to test if two different values are equal to a third
echo "CompareDateValues"
if [ "${TodaysDate}" = "${prevDate}" & "${currDate}" ]; then
echo "Dates Are A Match : TodaysDate:${TodaysDate} = savedStateRunDates:${prevDate}"
else
echo "Dates Are Not A Match : TodaysDate:${TodaysDate} = savedStateRunDates:${prevDate}"
echo Exit
exit 1
fi
As you can see from the code above I am trying to test if prevdate and currdate match Todaysdate but I can seem to get it working any help would be great
You have to use two conditions:
if [ "$TodaysDate" = "$prevDate" ] && [ "$TodaysDate" = "$currDate" ] ; then
or the -a operator (not recommended)
if [ "$TodaysDate" = "$prevDate" -a "$TodaysDate" = "$currDate" ] ; then
or, if you're in bash, switch to [[ ... ]] conditions:
if [[ $TodaysDate = $prevDate && $TodaysDate = $currDate ]] ; then
if test "$TodaysDate" = "$prevDate" && test "$TodaysDate" = "$currDate"; then ...
I have a shellscript that tells me missing ] in the line
if [ $status != "2" && $status != "3" && `echo "$temp1 > $upperLimit" | bc` = "1" ]
and also missing ] in the line
if [ $status = "2" && `cat motionsensordate` \> `date +%s` ]
Why is that?
The single [ doesn't support logical operators inside the brackets. You have to use them outside
if [ "$status" != 2 ] && [ "$status" != 3 ] ...
Use double quotes for variables in single brackets to prevent unary operator expected error when the variable is empty.
Or, switch to double brackets:
if [[ $status != 2 && $status != 3 ... ]]
Also, status different to 2 and 3 can be expressed by a pattern:
if [[ $status != [23] && ... ]]
And if you would like to (in addition to the answers here) group together conditions:
if [[ ( COND1 || COND2 ) && COND3 ]]
then
echo "$cmd"
break
fi
I'm trying to check if both conditions return the expected values.
I want to be sure that both return the expected value before continuing...
My problematic line is: if [ [ $ansmob = "y" ] || [ $flagbook != "1" ] ];
read -r -p "Would you like to add $site.booking.local as well? [y/n] " ansbook
if [ $ansbook = "y" ];
then sed "s/ServerAlias.*/& $site.booking.local/" -i $workdir/$site$dom.conf
flagbook="1"
fi
read -r -p "Would you like to add m.$site.booking.local? [y/n] " ansmob
if [ [ $ansmob = "y" ] || [ $flagbook != "1" ] ];
then sed "s/& $site.booking.local/& $site.booking.local m.$site.booking.local/" -i $workdir/$site$dom.conf
else
sed "s/ServerAlias.* /& m.$site.booking.local/" -i $workdir/$site$dom.conf
flagmobile="1"
fi
Replace
if [ [ $ansmob = "y" ] || [ $flagbook != "1" ] ];
with
if [ "$ansmob" = "y" ] || [ "$flagbook" != "1" ]
with bash's double brackets, you can use && and ||
if [[ $ansmob = "y" || $flagbook -ne 1 ]]
Within double brackets, it's not strictly necessary to quote the variables: this command is smart about evaluating expressions with empty variables.
The binary && operator is the syntax for the AND operation.