This doesn't work on /bin/sh
Main Topics
Browse All TopicsHello,
I am using /bin/sh as my shell and writing a shell script for this shell.
I have few operations that involve bitwise AND and bitwise OR operations to be done.
I want your help for doing this in a shell script.
Regards,
Narendra
This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.
Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.
If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.
Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.
Access the answers to your technology questions today.
30-day free trial. Register in 60 seconds.
Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Try it out and discover for yourself.
30-day free trial. Register in 60 seconds.
Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.
There are a couple of options in bourne shell.
#!/bin/sh
num=7
if [ "$num" -ge 6 ] && [ "$num" -le 8 ] ; then
echo "The first AND statement works."
else
echo "The first AND statement failed."
fi
if [ "$num" -ge 6 -a "$num" -le 8 ] ; then
echo "The second AND statement also works."
else
echo "The second AND statement also failed."
fi
if [ "$num" -eq 7 -o "$num" -eq 8 ] ; then
echo "The first OR statement works."
else
echo "The first OR statement failed."
fi
if [ "$num" -eq 7 ] || [ "$num" -eq 8 ] ; then
echo "The second OR statement also works"
else
echo "The second OR statement also failed."
fi
I am working with a old script and it uses sh.
So, I will not be able to change it to ksh or bash.
Also, I don't want to use perl. (I am working on something related to OS and nobody has used perl till now and hence I also don't want to use it)
So, none of the solutions suggested till now works for me.
Is there any other solution other than what is suggested till now?
Thanks for this oz.
I will remind again. I am not allowed to use bash, csh or perl inside this script.
Even in case, I use bash (or perl), your suggestion is not working.
Here is the sample script that I have:
#!/bin/sh
nm1=ff
N1=10
F1=`bash -c 'echo $(( $N1&$nm1 ))'`
#F1=`perl -e 'print $N1&$nm1'`
echo F1 = $F1
This throws error.
Here, N1 is decimal and nm1 is hexadecimal.
You have any corrections for this?
Thanks,
Narendra
Hello devrick0,
I think, you didn't understand the question properly.
I am not looking for Logical AND/OR operations.
I am looking for 'BITWISE' AND/OR operations.
Suppose I do AND of 5 and 6. The result has to be 4.
If I do OR of 5 and 6. The result has to be 7.
So, does your code do this?
Hope you got my point!?
> It's written solely in bourne shell (or, sh as you like to call it).
Bourne shell is not sh. It is bash. Both are different (though many times they look very similar)
Thanks,
Narendra
> I am using /bin/sh ..
traditional sh has no bitwise operators
> .. I am not allowed to use bash, csh or perl inside this script.
can you use some other tools?
echo 0|gawk '{print and(5,6)}'
echo 0|gawk '{print or(5,6)}'
> Bourne shell is not sh. It is bash.
wrong
sh is Bourne shell, bash is born/Bourne again shell
I stand corrected (on the bitwise portion of my response). I had overlooked that, saw the AND/OR comparisons in bourne shell, and went with it.
For future reference (excerpt from O'Reilly's UNIX Power Tools book).
sh:
The Bourne shell (named after its creator, Steve Bourne). This is the oldest of the current UNIX shells
and is available on most UNIX systems. (Some systems have replaced sh with a newer shell, like ksh
or bash, that has the features of sh and more.) It is a bit primitive and lacks job control features (the
ability to move jobs from the foreground to the background). Most UNIX users consider the Bourne
shell superior for shell programming or writing command files.
bash:
The "Bourne−again" shell developed by the Free Software Foundation (52.9). bash (8.2) is fairly
similar to the Korn shell. It has many of the C shell's features, plus history editing and a built−in help
command.
Hi devrick0,
Thanks for pointing to reference in O'Reilly.
As, I said before, it is also telling that sh and bash are different. (That's the reason they have different executables)
All the features of sh may work in bash and bash is very good, user friendly and also very powerfull.
But, all the features of bash will not work in sh!
Anyway, the solution suggested by ozo is working.
The only problem is they are using either bash or perl or creating temporary files.
I am waiting to see, if there are any other alternative solutions for this.
Please do suggest.
Thanks,
Narendra
Bitwise operators implemented with only Bourne Shell builtins, expr, and cut. Please tell me my usage of expr and cut are POSIX compliant...
#!/bin/sh
HIGHEST_BIT_MASK=214748364
# [/test builtin barfs on this. expr here on Linux seems to support 64 bit though.
#HIGHEST_BIT_MASK=92233720
bit_pairs_op() {
if [ $# -ne 3 ]; then
echo "Usage: bit_pairs_op <num1> <op> <num2>" >&2
exit 0
fi
NUM1=$1
NUM2=$3
OP=$2
MASK=$HIGHEST_BIT_MASK
while [ $MASK -gt 0 ]; do
BIT1=`expr $NUM1 / $MASK`
if [ $BIT1 -eq 1 ]; then
NUM1=`expr $NUM1 - $MASK`
fi
BIT2=`expr $NUM2 / $MASK`
if [ $BIT2 -eq 1 ]; then
NUM2=`expr $NUM2 - $MASK`
fi
expr $BIT1 $OP $BIT2
MASK=`expr $MASK / 2`
done
}
binary_to_decimal() {
if [ $# -ne 1 ]; then
echo "Usage: binary_to_decimal <binary>" >&2
exit 0
fi
BINARY=$1
MASK=$HIGHEST_BIT_MASK
BITNUM=1
DECIMAL=0
while [ $MASK -gt 0 ]; do
BIT=`echo $BINARY | cut -c$BITNUM`
if [ $BIT -eq 1 ]; then
DECIMAL=`expr $DECIMAL + $MASK`
fi
MASK=`expr $MASK / 2`
BITNUM=`expr $BITNUM + 1`
done
echo $DECIMAL
}
or() {
if [ $# -ne 2 ]; then
echo "Usage: op <num1> <num2>" >&2
exit 0
fi
eval `bit_pairs_op $1 + $2 | or_result`
echo "$RESULT_BITS"
}
or_result() {
RESULT_BITS=""
while read RESULT; do
if [ $RESULT -gt 0 ]; then
RESULT_BITS="${RESULT_BITS
else
RESULT_BITS="${RESULT_BITS
fi
echo "RESULT_BITS=$RESULT_BITS"
done
}
and() {
if [ $# -ne 2 ]; then
echo "Usage: and <num1> <num2>" >&2
exit 0
fi
eval `bit_pairs_op $1 + $2 | and_result`
echo "$RESULT_BITS"
}
and_result() {
RESULT_BITS=""
while read RESULT; do
if [ $RESULT -eq 2 ]; then
RESULT_BITS="${RESULT_BITS
else
RESULT_BITS="${RESULT_BITS
fi
echo "RESULT_BITS=$RESULT_BITS"
done
}
xor() {
if [ $# -ne 2 ]; then
echo "Usage: and <num1> <num2>" >&2
exit 0
fi
eval `bit_pairs_op $1 - $2 | xor_result`
echo "$RESULT_BITS"
}
xor_result() {
RESULT_BITS=""
while read RESULT; do
if [ $RESULT -eq -1 ]; then
RESULT_BITS="${RESULT_BITS
else
RESULT_BITS="${RESULT_BITS
fi
echo "RESULT_BITS=$RESULT_BITS"
done
}
if [ $# -ne 3 ]; then
echo "Usage: $0 <num1> <op> <num2>"
exit 1
fi
binary_to_decimal `$2 $1 $3`
Problem lies in conversion from HEX to decimal .
Use bc to get it done and use sh -c instead of bash/ksh/perl if you orig script is in "sh".
#!/bin/sh
#Since bc accepts A-F only not a-f
nm1=FF
N1=10
#That's it convert Hex into decimal
nm2=`expr "ibase=16; $nm1;" | bc`
#voila got it ....!
F1=`sh -c 'echo $(( $N1&$nm2 ))'`
Thanks
Dinesh
Nope
no inbuilt conversion from hex to decimal is possible , as far as awk is concerned.
Try following
echo "FF" | awk '{ printf "%d",$0 }'
and
echo "55" | awk '{ printf "%x",$0 }'
First gives 0, second gives 37.
As soon as awk encounters any alphabet 'A-F','a-f',0x,
It is giving 0.
I have checked it.
Thanks
Dinesh
I am accepting the answers gave by ozo.
Only they were near to the solution.
But, it also didn't work out.
I don't know if many people understand what it means to write a code in the operating system.
We will have lot of constraints.
We will not be having so many shells. Only sh is available.
So, using ksh or bash or csh is ruled out.
And using perl or awk or any other tool means adding a dependency. Nobody in OS programming will accept dependency.
The question that will be asked is, what if we don't have the tool? Then our solution will fail!!
That's the reason I didn't give A for the soltuion.
I am very sorry for that.
Regards,
Narendra
Business Accounts
Answer for Membership
by: ozoPosted on 2005-12-27 at 20:41:35ID: 15560675
#!/usr/bin/bash
echo echo $(( 5 & 6 ))
echo $(( 5 | 6 ))