Help with bash shell scripting

Use and complete the template provided. The entire template must be completed. If you don't, your post may be deleted!

  1. The problem statement, all variables and given/known data:

Write a bash shell script that takes as an argument a name. Then your script will ask the user for two numbers. It should then display the name and the sum (addition) and product (multiplication) of the two numbers

I don't know how to get numbers and add them

  1. Relevant commands, code, scripts, algorithms:

echo Please, enter your name

  1. The attempts at a solution (include all code and scripts):
    #!/bin/bash
    echo Please, enter your name
    read NAME
    echo "$NAME!"

  2. Complete Name of School (University), City (State), Country, Name of Professor, and Course Number (Link to Course):

Sheridan, Brampton Canada, SYST13416 LinuxUNIXOperating Systems
Martin

Note: Without school/professor/course information, you will be banned if you post here! You must complete the entire template (not just parts of it).

Well, numbers often come from string data, for instance if first argument on the command line, "$1". You can read text in from the keyboard and pattern-test it to ensure it is valid text. Bash and ksh support $(( )), which does all sorts of integer arithmetic, e.g., z=$(( $z + 1 )), and if (( )), which allows all sorts of integer tests, e.g., if (( $z < 30 )). I am not sure they have a friendly floating point, probably. Let me google a bit . . . no, bash does not. I use dc or bc to do my floating point calculations within scripts, or move to a more formal language. The text from bc can be tested to see if it is negative, for instance.

That's redundant. ((z=z+1)) or even ((z++))

But then it might not be ksh portable!

$ echo "(( 1 + 2 ))"
(( 1 + 2 ))
$ echo (( 1 + 2 ))  
ksh: syntax error: `((' unexpected
$ echo $(( 1 + 2 ))
3
$

Integer limited 31 bit signed, not much error checking:

$ z=1;while [ 1 ]
do
echo $z
z=$(( $z + $z ))
done 2>&1|pg
1
2
4
8
16
32
64
128
256
512
1024
2048
4096
8192
16384
32768
65536
131072
262144
524288
1048576
2097152
4194304
8388608
16777216
33554432
67108864
134217728
268435456
536870912
1073741824
-2147483648
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0

[quote=dgpickett;302513199]
But then it might not be ksh portable!

$ echo "(( 1 + 2 ))"
(( 1 + 2 ))
$ echo (( 1 + 2 ))
ksh: syntax error: `((' unexpected That's not "unportable" -- that's simply wrong.  BASH and KSH alike agree this is a syntax error, and for good reason:

Produces a string:  $((stuff))
Produces no string: ((stuff))

Plain (( )) without the $ is more like a [ ] statement.  Try it:  if ((0)) ; then echo asdf ; fi
if ((1)) ; then echo asdf ; fi

When you use them in a syntactically valid manner, as their own statement, they're fine: ((k = k + 5))

You also missed my point about k vs $k inside (( )). ((k=k+3)) works, (($k=$k+3)) does not since K gets substituted before anything starts calculating, so you end up trying to assign the value of 3 or something. Just plain variable names don't ever need a $ inside a (( )) expression anyway, why make them more complicated?

Thanks for the (()) tuneup. k=$(( $k + 5 )) might be longer, but more obvious and intuitive for the beginner than (( k += 5 )).

Is there a cost difference if k is typeset integer between different syntaxes?

I think that the (( expression )) is not standard.
The $(( expression )) is standard.

If that matters, of course.

Well, there are many ksh clones out there, but ksh93 is free. It works in my 1988 HPUX 11_00 ksh. It even works in my 1988 sh:

$ sh -c 'k=1 ; (( k += 5 )) ; echo $k'
6
$

Yes,
as far as I know it works with all Korn Shell variants,
I'm only saying that it's not POSIX.

zsh-4.3.11[radoulov]% ksh -c '((x=x+3)); echo $x'
3
zsh-4.3.11[radoulov]% mksh -c '((x=x+3)); echo $x'
3
zsh-4.3.11[radoulov]% pdksh -c '((x=x+3)); echo $x'
3
zsh-4.3.11[radoulov]% ash -c '((x=x+3)); echo $x'

zsh-4.3.11[radoulov]% dash -c '((x=x+3)); echo $x'

zsh-4.3.11[radoulov]% posh -c '((x=x+3)); echo $x'

zsh-4.3.11[radoulov]% 

---------- Post updated at 09:56 PM ---------- Previous update was at 09:53 PM ----------

It works on HP-UX because its /usr/bin/sh is ksh88.
Try it with /bin/sh on Solaris :slight_smile:

I suspected something such, as the sh executable is separate, bigger and newer.

I can never sort out the culture wars between POSIX, AT&T SVR?, LINUX, GNU, BSD and all the prop. players: AIX, Solaris, HP-UX, ???? I know they keep changing the regex, so I have to worry about which library path which program runs under. I want my \< and \> back!

Yes,
they are different :slight_smile:

Regarding the shell, Sven Mascheck maintains a great site,
there is page dedicated to the various system shells:

www.in-ulm.de/~mascheck/various/shells/

It'd be neat to chart them and their sometimes shared idiosyncracies! I should google for it! :smiley:

Well k is not guaranteed to behave the same way as $k inside an integer expression. It depends on the content of k. Example:

$
$
$ a="2+2"
$ b="3+3"
$ ((c = a * b )) ; echo $c
24
$ ((c = $a * $b )) ; echo $c
11
$

Returning to original question... Here is one way to get a number...

$ cat getn
#! /usr/bin/ksh

printf "Enter a number - "
read number

printf "you entered %d \n" $number

exit 0

$
$
$ ./getn
Enter a number - 77
you entered 77
$

I think you should be able to expand it to get 2 numbers. And you seem to have a complete discussion on adding them. :slight_smile:

Doesn't get it outside, k=$(( $k + 3 )), so that is not an issue.

I like 11 as the right answer, so $ is necessary? Mult takes precedence over + ? Or left to right, it should be 15. Ugly! I always use paren. no priority applicable.

Thanks for all the help, I got it

Longer, less intuitive(some k's need $ and some don't), and has many unintended side-effects. ((k=k+5)) will work. Failing that, why not just use expr?

I tested the syntax on the absolute 'worst' ksh I could find.