Break for loop if variable is false - unix

Trying to break a for loop if the variable $DEVP doesn't exist.
nme=(Y6T1 Y6-T1 Y6.T1 Yr6T1 Yr6-T1 Yr6.T1 Yr6Term1)
DEVP=(/dev/disk2 /dev/disk3 /dev/disk4 /dev/disk5 /dev/disk6 /dev/disk7 /dev/disk8)
for ((i = 0; i < 7; i++)) ; do
if [ ${nme[i]} ${DEVP[i]} = 0 ] ; then
diskutil eraseDisk FAT32 ${nme[i]} ${DEVP[i]}
else
echo “Formatted USBs” ; break
fi
done

The break works fine
for ((i = 0; i < 7; i++)) ; do
if [ $i -lt 3 ] ; then
echo $i
else
echo “Formatted USBs” ; break
fi
done
Output is:
0
1
2
“Formatted USBs”
, however I'm not sure regarding your if statement, you should probably use -z.
if [ -z ${DEVP[i]} ] ; then
Have a look here

Your comparison looks like you expect the two strings to contain the single number zero. They never will. If they are empty, they will contain the empty string. (But even then having two string arguments to the left of the comparison operator is a syntax error.)
Anyway, if the actual problem you are trying to solve is that you don't know how many elements these arrays contain, just ask.
for((i=0; i<${#DEVP[#]}; ++i)); do
Of course, if the arrays contain a different number of arguments, you could still end up in a situation where ${nme[i]} is undefined.
${nme[i]+:} break
This is rather obscure -- it will expand to the empty string before break (and thus break out of the loop) if the value is unset; if it's set, this is just a : noop.

First repair the syntax: Put things in quotes in the if statement.
EDIT: I thought you needed to refer to the var i with $i, but #tripleee showed me, that this is optional in bash arrays. I removed the extra $ characters.
nme=(Y6T1 Y6-T1 Y6.T1 Yr6T1 Yr6-T1 Yr6.T1 Yr6Term1)
DEVP=(/dev/disk2 /dev/disk3 /dev/disk4 /dev/disk5 /dev/disk6 /dev/disk7 /dev/disk8)
for ((i = 0; i < 7; i++)) ; do
if [ "${nme[i]} ${DEVP[i]}" = 0 ] ; then
echo "diskutil eraseDisk FAT32 ${nme[i]} ${DEVP[i]}"
else
echo “Formatted USBs” ; break
fi
done
If you want to check the vars being empty, introduce an error by looping until 8.
I have put an echo in front of the diskutil line, so you can test without doing something you do not want.
for ((i = 0; i < 8; i++)) ; do
if [ -z "${nme[i]}" ]; then
echo "loop $i: \${nme[i]} is empty";
break;
fi
if [ -z "${DEVP[i]}" ]; then
echo "loop $i: \${DEVP[i]} is empty";
break;
fi
echo "diskutil eraseDisk FAT32 ${nme[i]} ${DEVP[i]}"
done

Related

bjam - cannot assign a literal to a variable?

Well, this must be the most stupid and idiotic behavior I've seen from a programming language.
https://www.bfgroup.xyz/b2/manual/release/index.html says:
Syntactically, a Boost.Jam program consists of two kinds of
elements—keywords (which have a special meaning to Boost.Jam) and
literals. Consider this code:
a = b ;
which assigns the value b to the variable a. Here, = and ; are
keywords, while a and b are literals.
⚠ All syntax elements, even
keywords, must be separated by spaces. For example, omitting the space
character before ; will lead to a syntax error.
If you want to use a literal value that is the same as some keyword,
the value can be quoted:
a = "=" ;
OK, so far so good. So I have this in my Jamroot:
import path : basename ;
actions make_mytest_install
{
echo "make_mytest_install: MY_ROOT_PATH $(MY_ROOT_PATH) PWD $(PWD:E=not_set)" ;
epath = "$(MY_ROOT_PATH)/projects/mytest/bin/gcc-9/release/qt5client" ;
ename = basename ( $(epath) ) ;
echo "epath $(epath) ename $(ename)" ;
}
explicit install-gettext ;
make install-mytest : : #make_mytest_install ;
... and I try this:
bjam install-mytest
...updating 1 target...
Jamfile</home/USER/src/myproject>.make_mytest_install bin/install-mytest
make_mytest_install: MY_ROOT_PATH /home/USER/src/myproject PWD not_set
[ SHELL pstree -s -p 2720269 && echo PID 2720269 PWD /home/USER/src/myproject ]
/bin/sh: 13: epath: not found
/bin/sh: 14: Syntax error: "(" unexpected
.....
...failed Jamfile</home/USER/src/myproject>.make_mytest_install bin/install-mytest...
...failed updating 1 target...
Now - how come that the SIMPLEST assignment to a string, EXACTLY AS in the manual:
epath = "$(MY_ROOT_PATH)/projects/mytest/bin/gcc-9/release/qt5client" ;
... fails, and this variable cannot be found anymore?
What is the logic in this? How the hell is this supposed to work? I would get it if MY_ROOT_PATH was undefined - but the echo before it, shows that it is not? What is this lunacy?
So I cannot believe I'm asking something this trivial, but:
How do you assign a string to a variable in bjam language?
Well, the error gives somewhat of a hint: /bin/sh: -> so apparently inside actions, it is sh that runs - then again, if it was really sh I could have assigned variables, but I can't. So best I could do, was to remove the assignments OUT of actions:
import path : basename ;
epath = "$(MY_ROOT_PATH)/projects/mytest/bin/gcc-9/release/qt5client" ;
# ename = basename ( $(epath) ) ; # nope, causes target install-mytest to not be found :(
# calling a shell for basename works - but adds a damn NEWLINE at end!?!?!?!
ename = [ SHELL "basename $(epath)" ] ;
actions make_mytest_install
{
echo "make_mytest_install: MY_ROOT_PATH $(MY_ROOT_PATH) PWD $(PWD:E=not_set)" ;
echo "epath $(epath) ename $(ename)" ;
}
explicit install-mytest ;
make install-mytest : : #make_mytest_install ;
So, assignment kind of passes, but you still can't get the basename ?!
I still don't understand, who thought this kind of variable management is a good idea ... I don't even understand, how people managed to build stuff with this system

tcl fibonacci series in recursive

I have tried this not working ... Can anyone help please ? Want to know logic mistake or the syntax. Thanks in advance.
#*********************************************
puts "Fibbonocci sequence"
proc fibb {size} {
if { $size == 1 || $size ==0 } {
return $size
} else {
return [expr fibb [expr $size - 1] + fibb [expr $size - 2]]
}
}
puts "Enter the length of the series:"
set n [gets stdin]
puts "Fibbonocci sequence upto $n terms are:"
puts [fibb $n]
#**********************************************
The problem is this line:
return [expr fibb [expr $size - 1] + fibb [expr $size - 2]]
Actually, that's got several problems. The first is that the expressions aren't braced:
return [expr { fibb [expr { $size - 1 }] + fibb [expr { $size - 2 }] }]
The second problem is that you have to call fibb as a Tcl command within that outer expression, so more [brackets] are needed:
return [expr { [fibb [expr { $size - 1 }]] + [fibb [expr { $size - 2 }]] }]
Plug that into the right place and the rest of your code should work…
But we can be more elegant than that by turning fibb into a function. Functions in Tcl are really just commands that live in the right namespace, tcl::mathfunc.
proc tcl::mathfunc::fibb {size} {
if { $size == 1 || $size ==0 } {
return $size
}
return [expr { fibb($size-1) + fibb($size-2) }]
}
Then you invoke it using, say:
puts [expr { fibb($n) }]
The only difference is that we've put the command (i.e., the procedure) in the right namespace so that it behaves as an expression component. And we've still put braces around the expression (please always do that until you at least understand why it matters) and simplified the code very slightly.
Also, you can still invoke it directly:
puts [tcl::mathfunc::fibb $n]
That'll work just the same way.

Unix: Want to match the number and return should be exact match or just lesser number

My input will be as: 04.02.03.00
and my other list will be 04.02.01.00, 04.02.02.00 & 04.02.05.00.
After comparing the input(04.02.03.00) with the given list if the exact match(04.02.03.00) is not in the list then 04.02.02.00 should return as output.
You can use the following as an example with bash
read INPUT
for STRING in 04.02.01.00 04.02.02.00 04.02.05.00
do
if [[ "$INPUT" = $STRING ]]
then
FOUND=1
fi
done
if [[ FOUND -ne 1 ]]
then
echo 04.02.02.00
fi
i agree with Michael just in order that to work i think it would need the "test", so like this. the brackets would help you though protect urself from null variables but thats matter of opinion.
read INPUT
for STRING in 04.02.01.00 04.02.02.00 04.02.05.00
do
if test "$INPUT" = $STRING
then
FOUND=1
fi
done
if test $FOUND -ne 1
then
echo 04.02.02.00
fi

Special characters within an If condition

I am trying to write an if statement which checks if the first two characters of particular variable starts with '$$'. I have tried the following but the if condition is always evaluating to true.
var1=$$abc
var2=$$def
var1_cut=`echo $var1 | cut -c -2`
var2_cut=`echo $var2 | cut -c -2`
if [[ $var1_cut == "$$" && $var2_cut== "$$" ]]
then
break
else
echo $var1
fi
Could anyone help me out here. Is there anything to watch out for while trying to match $$ in if statements
Use single quotes to avoid expansion and double while comparing.
If you are using bash, you don't need to use cut. You can do that in bash itself.
var1='$$abc'
var2='$$def'
var1_cut=${var1:0:2}
var2_cut=${var2:0:2}
if [[ "$var1_cut" == '$$' && "$var2_cut" == '$$' ]]
then
# Do something
else
echo "$var1"
fi

side effect of zsh echo?

For some reason this script will work with all of the 'echo's at the end, but without them $wall is an empty string. This seems like really odd behaviour.
#!/bin/zsh
if [ ! -n "$1" ] ; then
files=(~/pictures/backgrounds/*jpg)
else
while [ $1 ] ; do
files+=(`echo $1/*jpg`)
shift
done
fi
echo $files
N=${#files}
echo $N
((N=RANDOM%N))
echo $N
wall=${files[$N]}
echo $wall
cp $wall ~/wall.jpg
This code will sometimes fail because RANDOM%N can result in zero and zsh array indexes start with 1. You should use RANDOM%N+1 instead.
You can:
setopt ksharrays
to enable zero-based indexing.
From man zshoptions:
Emulate ksh array handling as closely as possible. If this
option is set, array elements are numbered from zero, an array
parameter without subscript refers to the first element instead
of the whole array, and braces are required to delimit a sub‐
script (${path[2]}' rather than just$path[2]').

Resources