# So weird



## abdelilah (Apr 27, 2011)

Hello everyone

I have to make a script which creates as much folders as declared by the user, the problem is that I've made a loop which doesn't seem to work can you please help :


```
#!/bin/sh
echo "Veuillez saisir un nombre"; read nmbr
nmbrf=$nmbr
while [ $nmbrf>0 ]
	do mkdir "foo$nmbrf"
	expr $nmbrf-1
done
```

Thanks in advance


----------



## wblock@ (Apr 27, 2011)

Homework, so we don't want to give it away... Run your script with -x, or add some echo or printf statements to show the values of the loop index.


----------



## SirDice (Apr 27, 2011)

Hint: the expr command isn't used correctly.


----------



## UNIXgod (Apr 27, 2011)

"The Variable : what it is and why we need them"
 by UNIX god.​
_( translated from octal to human from the 1967 filmstrip )
In the beginning the art of accessing memory addresses the indigenous people used the ancient technique of interpolation to create, record, update, and destroy a little primitive memory binding known simply as a variable.

The variable which initially held a numerical value would eventually be endowed to hold a whole array of interesting values. In the early days when the variable was of no use any more one of the most respected of all of the indigenous tribe known only as the 'garbage collector' would free() the variable by sacrificing it to the natives' deity known simply as the heap.

Though the native scripture warned them of Undefined Behaviour ... stack overflow ... hellfire ... segfault_

Seriously though break down what isn't working.

Start with your loop and counter as SirDice pointed out.

To do that experiment with expr() directly in the command line. build a counter you can call line by line. (READ THE MAN PAGE)

Also take the time to investigate the man page for sh(). I realise it's a long man page but it will be your best resource once you know the language( much like how our o'reilly books used to be) Hint: look at Quoting, Parameter Expansion, Command Substitution, Flow-Control Constructs and test()... did I mention READ THE MAN PAGES.

The Almquist Bourne shell is a great shell to work with. It takes some getting used to.

For further tutorials and best practices I have always enjoyed reading the stuff on this site:

http://www.shelldorado.com/

a more direct link to save you a couple clicks off of Heiner's site: http://www.shelldorado.com/shelltips/

Look at the beginner section.

After you get your bearings( in say 45 minutes) take the time to learn what NOT to do with the shell:

http://partmaps.org/era/unix/award.html
http://www.shelldorado.com/articles/ignorantsguide.html

Good luck! and don't forget READ THE man() PAGES!

~


----------



## vivek (Apr 27, 2011)

Most modern shell can do

```
mkdir foo{1,2,3}
```

As UNIXgod pointed out read the man page


----------



## abdelilah (Apr 27, 2011)

Thanks to all of you, I will check these answers tonight back home


----------



## abdelilah (Apr 30, 2011)

Hello

I've made a slight modification but the loop isn't effective since my tests stops on the lower value :


```
#!/bin/sh
echo "Veuillez saisir un nombre"; read nmbr
nmbrf=$nmbr
echo $nmbrf
while [ $nmbrf>0 ]
	#do mkdir "foo$nmbrf"
do	
	echo foo$nmbrf
	expr $nmbrf - 1
done
```

Result :

```
3
foo4
3
foo4
3
foo4
3
foo4
3
foo4
3
foo4
3
foo4
3
foo4
3
foo4
3
foo4
```

What is wrong with this loop, since the expr is working correctly.


----------



## abdelilah (Apr 30, 2011)

Hello again

I've made another change but I still have the same bug :

```
#!/bin/sh
echo "Veuillez saisir un nombre"; read nmbr
nmbrf=$nmbr
echo $nmbrf
#while [ $nmbrf > 0 ]
while test $nmbrf -gt 0
	#do mkdir "foo$nmbrf"
do
echo foo$nmbrf
expr $nmbrf - 1
done
```


----------



## wblock@ (Apr 30, 2011)

Always indent code properly, even temporary code.

expr is not doing what you think it's doing.  Add another echo after the expr line to show the value of $nmbrf at that point.


----------



## abdelilah (Apr 30, 2011)

But if it wasn't really working how come that the value of $nmbrf decreased ?


----------



## abdelilah (Apr 30, 2011)

Here again it shows that :

```
#!/bin/sh
echo "Veuillez saisir un nombre"; read nmbr
nmbrf=$nmbr
#echo $nmbrf
#while [ $nmbrf > 0 ]
while [ $nmbrf -gt 0 ]
	#do mkdir "foo$nmbrf"
do
#echo foo$nmbrf
	expr $nmbrf - 1
	echo "$nmbrf"
done
```

Terminal :

```
4
3
4
3
4
3
4
3
4
3
^C
```

I really think that c programming is much more easier, please help.


----------



## jalla (Apr 30, 2011)

abdelilah said:
			
		

> But if it wasn't really working how come that the value of $nmbrf decreased ?


What gives you the idea that $nmbrf is decreased?

One last hint

```
nmbrf=`expr $nmbrf - 1`
```


----------



## abdelilah (Apr 30, 2011)

The echo command shows a decreased value so I guess expr done the job
I've already done that but it crashes the scripts.

```
#!/bin/sh
echo "Veuillez saisir un nombre"; read nmbr
nmbrf=$nmbr
#echo $nmbrf
#while [ $nmbrf > 0 ]
while [ $nmbrf -gt 0 ]
	#do mkdir "foo$nmbrf"
do
#echo foo$nmbrf
	`expr $nmbrf - 1`
	echo "$nmbrf"
done
```

Here it is :

```
./scriptDevoir: line 10: 3: command not found
4
./scriptDevoir: line 10: 3: command not found
4
./scriptDevoir: line 10: 3: command not found
4
./scriptDevoir: line 10: 3: command not found
4
^C
```


----------



## abdelilah (Apr 30, 2011)

Thank you, but it is just the beginning :

```
#!/bin/sh
echo "Veuillez saisir un nombre"; read nmbr
nmbrf=$nmbr
#echo $nmbrf
#while [ $nmbrf > 0 ]
while [ $nmbrf -gt 0 ]
	#do mkdir "foo$nmbrf"
do
#echo foo$nmbrf
	nmbrf=`expr $nmbrf - 1`
	echo "$nmbrf"
done
```


```
Veuillez saisir un nombre
4
3
2
1
0
```


----------



## UNIXgod (May 1, 2011)

jalla said:
			
		

> One last hint
> 
> ```
> nmbrf=`expr $nmbrf - 1`
> ```





			
				abdelilah said:
			
		

> Thank you, but it is just the beginning



abdelilah please note how the backticks work. They are opening up a new shell in the background and inheriting everything defined in the parent shell. The subshell evaluates the command expression to be returned back to the parents variable.

simple decrementing counter example

```
(~) %  N=42; echo "=> ${N}"                                           
=> 42
(~) %  dec_N() {N=`expr $N + -1`; printf "=> N is now %d\n" $N;}      
(~) %  dec_N                                                          
=> N is now 41
(~) %  dec_N                                                          
=> N is now 40
(~) %  dec_N                                                          
=> N is now 39
```

Here is my english version of your program to show you how it can be accomplished with functions. Also note I only use one variable instead of two.


```
#!/bin/sh

get_NUM() {
        echo "Please enter a number: "
        read NUM
}

NUM_countdown() {
        while [ $NUM -gt 0 ]; do
                echo ${NUM}
                NUM=`expr $NUM + -1`
        done
        printf "LIFTOFF!\n"
}
get_NUM
NUM_countdown
```


----------



## jilles@ (May 1, 2011)

Instead of using expr in command substitution, consider using arithmetic expansion (see man sh()). For example:

```
nmbrf=$((nmbrf - 1))
```


----------



## abdelilah (May 1, 2011)

Thanks to all of you, the homework was accomplished.


----------

