binary AND from /bin/sh

binary AND from /bin/sh

Post by Stefan Monnie » Sat, 14 Jun 1997 04:00:00



How can I do binary AND and OR from a shell script ?
The closest I've got is to use /bin/expr's boolean AND and OR which
returns correct values in the special cases where one of the two arguments
is zero (or both have the same value), but this limitation is really annoying.

The idea is to use the most basic utility as possible (perl is not an option)
because it would be potentially used in a very restricted environment.

        Stefan

 
 
 

binary AND from /bin/sh

Post by Chris J ( » Sun, 15 Jun 1997 04:00:00


Use && and ||

Example:
#!/bin/sh
x=56
y=34
if [ $x = 56 ] && [ $y = 34 ]
then
        echo FISH
fi
if [ $x = 56 ] || [ $y = 1 ]
then
        echo CARROT
fi
if [ $x = 53 ] && [ $y = 34 ]
then
        echo ARMADILLO
fi
# end of script

Chris...



Quote:

>How can I do binary AND and OR from a shell script ?
>The closest I've got is to use /bin/expr's boolean AND and OR which
>returns correct values in the special cases where one of the two arguments
>is zero (or both have the same value), but this limitation is really annoying.

>The idea is to use the most basic utility as possible (perl is not an option)
>because it would be potentially used in a very restricted environment.

>        Stefan

--
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Chris Johnson                    | kernel, n.: A part of an operating system

http://pine.shu.ac.uk/~cjohnso0  |    of sorcery and black art.

 
 
 

binary AND from /bin/sh

Post by Stefan Monnie » Sun, 15 Jun 1997 04:00:00



Quote:> Use && and ||

No, I said "binary", not "boolean".

I want to have something like

        > binand 45 11
        9
        >

Using perl, binand would be defined by:

        binand () { perl -e 'print ('$1' & '$2', "\n")'; }

But perl is not available.

        Stefan

 
 
 

binary AND from /bin/sh

Post by Andrew Giert » Mon, 16 Jun 1997 04:00:00


[alt.unix.wizards added just for the hell of it]

writes:

 Stefan> I want to have something like

 >> binand 45 11
 >> 9
 >>

 Stefan> Using perl, binand would be defined by:

 Stefan>         binand () { perl -e 'print ('$1' & '$2', "\n")'; }

 Stefan> But perl is not available.

This is inspired by a CRC-calculating routine that I once wrote in COBOL
(don't ask!)

binor()  { echo "[[xi]p]p2o$1p$2p[+p]p[[p]p]p" | dc | dc | tr '2x' '12' | dc; }
binand() { echo "[[xi]p]p2o$1p$2p[+p]p[[p]p]p" | dc | dc | tr '12x' '012' | dc; }
binxor() { echo "[[xi]p]p2o$1p$2p[+p]p[[p]p]p" | dc | dc | tr '2x' '02' | dc; }

The basic mechanism is to convert the numbers to binary, do arithmetic
on them as though they were decimal, munge the output, and convert
back to decimal.

--
Andrew.

 
 
 

binary AND from /bin/sh

Post by Edward M. Le » Mon, 16 Jun 1997 04:00:00


Try

if [ test1 ] || [test2 ]]; then
        blah;
fi

or -> ||
and -> &&

man [    or
man test   and
man sh for more details

Cheers.



Quote:

> How can I do binary AND and OR from a shell script ?
> The closest I've got is to use /bin/expr's boolean AND and OR which
> returns correct values in the special cases where one of the two
arguments
> is zero (or both have the same value), but this limitation is really
annoying.

> The idea is to use the most basic utility as possible (perl is not an
option)
> because it would be potentially used in a very restricted environment.

>         Stefan

 
 
 

binary AND from /bin/sh

Post by Chris J ( » Mon, 16 Jun 1997 04:00:00


Oops...apologies. In that case, you can migrate your scripts to korn shell
scripts which can do arithmatic (binary or otherwise).

example:
[130%][pine][tmp] >cat /tmp/fish
#!/bin/ksh

x=56
y=34

echo $((x & y))

[131%][pine][tmp] >/tmp/fish
32
[132%][pine][tmp] >

I checked this was correct :-)
        56 (binary) = 111000
        34 (binary) = 100010
                      ------
                      100000 = 32

Similarly, you can use | to do logical or operations.

Chris...




>> Use && and ||

>No, I said "binary", not "boolean".

>I want to have something like

>        > binand 45 11
>        9

>Using perl, binand would be defined by:

>        binand () { perl -e 'print ('$1' & '$2', "\n")'; }

>But perl is not available.

>        Stefan

--
<-------------------------------+------------------------------------------->
Chris Johnson                   :  Epoch ends on Mon Jan 18 17:14:07 2038 GMT

http://pine.shu.ac.uk/~cjohnso0 :  UNIX will still be going strong :-)
 
 
 

binary AND from /bin/sh

Post by Stefan Monnie » Mon, 16 Jun 1997 04:00:00


cjohn...@linux2.cms.shu.ac.uk (Chris J (#6)) writes:

> Oops...apologies. In that case, you can migrate your scripts to korn shell
> scripts which can do arithmatic (binary or otherwise).

[... for the first time reading ksh's manpage ...]

Pretty good. As a zsh user, I was indeed missing many features in /bin/sh,
and I only now realize that most of those features are already available in
ksh, so it is indeed very tempting to move those scripts to ksh (and clean them
up at the same time). I'm still a little reluctant because those scripts are
used also from /etc/init.d and I'd like them to be portable and useable before
/usr is mounted. On another hand, it looks like XPG4-compliant shells are
quite able to evaluate $((1 &13)), so maybe there's hope ?

Is there any place that describes (or at least sketches) XPG4's /bin/sh
or compares it to older /bin/sh or to /bin/ksh ?

        Stefan

PS: as if I had plenty of time to spare, I even bothered to write a sed
    script that does the conversion to binary, the and/or/xor processing and
    the conversion back to decimal. Amazing how much you can do with sed
    and how tedious it is. Try it with

        > echo 'Blabla 450 & (110 | 45) & 11 et blibli 255 ^ 36' | sedscript
        Blabla 2 et blibli 219
        >

#!/bin/sed -f

# canonicalize the input
s/^/ /

###############################################################################
###                       convert to binary                                 ###
###############################################################################

### add mark used during processing ###
s/$/#/
h

# do for each number
:bincvt-numbers
/[0-9].*#/{

    ### extract the number to process ###
    s/^\(.*[^0-9]\)\([0-9][0-9]*\)\(.*\)#\(.*\)/\2/
    x
    # the (future) output is kept in the hold space
    s/^\(.*[^0-9]\)\([0-9][0-9]*\)\(.*\)#\(.*\)/\1#\3\4/
    x

    ### convert one bit at a time ###    
    :bincvt-digits
    /./{
        # divide by 2 and keep carries (digits are renamed to letters)
        s/0/a,a/g
        s/1/a,f/g
        s/2/b,a/g
        s/3/b,f/g
        s/4/c,a/g
        s/5/c,f/g
        s/6/d,a/g
        s/7/d,f/g
        s/8/e,a/g
        s/9/e,f/g

        # process the carries
        s/,fa/5/g
        s/,fb/6/g
        s/,fc/7/g
        s/,fd/8/g
        s/,fe/9/g
        s/,aa/0/g
        s/,ab/1/g
        s/,ac/2/g
        s/,ad/3/g
        s/,ae/4/g

        # rename letters back to digits        
        s/a/0/g
        s/b/1/g
        s/c/2/g
        s/d/3/g
        s/e/4/g
        s/f/5/g

        # check the last bit and accumulate the result in the hold space        
        /,5/{
            s/,5//
            x
            s/#/#1/
            x
        }
        /,0/{
            s/,0//
            x
            s/#/#0/
            x
        }

        # trim leading zeroes
        s/^0*//

        b bincvt-digits
    }
    # get the result out of the hold space
    g

    b bincvt-numbers

}

# clean up the temporary marks
s/#//

# as long as there are expressions to process, loop
: expr-process

###############################################################################
###                     process binary XOR                                  ###
###############################################################################

# put marks to facilitates locating XOR operations while in progress
s/\([01][01]*\) *\^ *\([01][01]*\)/#\1^#\2#/g

# as long as there are bits to XOR, and them
:xor-process
/#\([01]*\)[01]\^\([01]*\)#\([01]*\)[01]#/{
    s/#\([01]*\)0\^\([01]*\)#\([01]*\)0#/#\1^0\2#\3#/g
    s/#\([01]*\)0\^\([01]*\)#\([01]*\)1#/#\1^1\2#\3#/g
    s/#\([01]*\)1\^\([01]*\)#\([01]*\)0#/#\1^1\2#\3#/g
    s/#\([01]*\)1\^\([01]*\)#\([01]*\)1#/#\1^0\2#\3#/g
    b xor-process

}

# concatenate the remaining bits in front of the result and remove the marks
s/#\([01]*\)\^\([01]*\)#\([01]*\)#/\1\3\2/g

###############################################################################
###                     process binary AND                                  ###
###############################################################################

# put marks to facilitates locating AND operations while in progress
s/\([01][01]*\) *& *\([01][01]*\)/#\1\&#\2#/g

# as long as there are bits to AND, and them
:and-process
/#\([01]*\)[01]&\([01]*\)#\([01]*\)[01]#/{
    s/#\([01]*\)0&\([01]*\)#\([01]*\)0#/#\1\&0\2#\3#/g
    s/#\([01]*\)0&\([01]*\)#\([01]*\)1#/#\1\&0\2#\3#/g
    s/#\([01]*\)1&\([01]*\)#\([01]*\)0#/#\1\&0\2#\3#/g
    s/#\([01]*\)1&\([01]*\)#\([01]*\)1#/#\1\&1\2#\3#/g
    b and-process

}

# drop the remaining bits and remove the marks
s/#\([01]*\)&\([01]*\)#\([01]*\)#/\2/g

###############################################################################
###                     process binary OR                                   ###
###############################################################################

# put marks to facilitates locating OR operations while in progress
s/\([01][01]*\) *| *\([01][01]*\)/#\1|#\2#/g

# as long as there are bits to AND, and them
:or-process
/#\([01]*\)[01]|\([01]*\)#\([01]*\)[01]#/{
    s/#\([01]*\)0|\([01]*\)#\([01]*\)0#/#\1|0\2#\3#/g
    s/#\([01]*\)0|\([01]*\)#\([01]*\)1#/#\1|1\2#\3#/g
    s/#\([01]*\)1|\([01]*\)#\([01]*\)0#/#\1|1\2#\3#/g
    s/#\([01]*\)1|\([01]*\)#\([01]*\)1#/#\1|1\2#\3#/g
    b or-process

}

# concatenate the remaining bits in front of the result and remove the marks
s/#\([01]*\)|\([01]*\)#\([01]*\)#/\1\3\2/g

###############################################################################
###                     process parenthesis                                 ###
###############################################################################

/( *\([01][01]*\) *)/{
    s/( *\([01][01]*\) *)/\1/g

}

### loop if there's anything left to reduce
/\([01][01]*\) *[|&^] *\([01][01]*\)/b expr-process

###############################################################################
###                     convert to decimal                                  ###
###############################################################################

# add the usual mark
s/$/#/

# convert each number
:deccvt-numbers
/[01].*#/{

    ### move the mark to the right place ###
    s/^\(.*[^01]\)\([01][01]*\)\(.*\)#\(.*\)/\1#\2\3\4/
    # clear the hold space
    x
    s/^.*$//
    x

    # process each bit
    :deccvt-digits
    /#[01]/{

        ### turn the top bit into a carry
        /#0/{
            s/#0/#/
            x
            s/$/a/
        }
        /#1/{
            s/#1/#/
            x
            s/$/b/
        }

        ### multiply by 2 and keep carries (again, letters are used)
        s/0/a,a/g
        s/1/a,c/g
        s/2/a,e/g
        s/3/a,g/g
        s/4/a,i/g
        s/5/b,a/g
        s/6/b,c/g
        s/7/b,e/g
        s/8/b,g/g
        s/9/b,i/g

        ### process carries
        s/,aa/0/g
        s/,ab/1/g
        s/,ca/2/g
        s/,cb/3/g
        s/,ea/4/g
        s/,eb/5/g
        s/,ga/6/g
        s/,gb/7/g
        s/,ia/8/g
        s/,ib/9/g

        # turn letters back into digits
        s/a/0/g
        s/b/1/g

        # remove leading zeroes
        s/^0*\(.\)/\1/

        x
        b deccvt-digits
    }

    # move the output from the hold space into the text (right after the mark)
    s/$/#/
    G
    s/#\(.*\)#\n\([0-9]*\)$/#\2\1/

    b deccvt-numbers

}

# cleanup the temp mark
s/#//

# de-canonicalize the output
s/^ //

 
 
 

binary AND from /bin/sh

Post by Pete Houst » Thu, 19 Jun 1997 04:00:00



#No, I said "binary", not "boolean".
#
#I want to have something like
#
#        > binand 45 11
#        9
#        >
...
#But perl is not available.

But cc is. No problemo.

                        Pete

Of course, the best soln is assembler - should be lightning fast and
trivial to code.

 
 
 

1. #!/bin/sh #!/usr/bin/sh can I do both for 2 diff machines

I'd like the same script to run on 2 different machines, Hp and Sun.
The problem is that sh resides in different directories.  Is there
a way to have exec look in two places?

P.S.  No, I don't have write access to /usr/bin, or /bin

Any help appreciated,

John
--
_________________________________________________________________
Office phone: 503-737-5583 (Batcheller 349);home: 503-757-8772
Office mail:  303 Dearborn Hall, OSU, Corvallis, OR  97331
_________________________________________________________________

2. Motif

3. more secure?: "#!/bin/sh -" or "#!/bin/sh"

4. Any freeware can replace "Solaris Bandwidth Manager"????

5. portable solution of /bin/sh true-false binary flag?

6. dual-head setup -- please help

7. root's shell, /sbin/sh, /bin/sh and /usr/ksh

8. workspace-menu font

9. Any difference between /sbin/sh and /bin/sh?

10. diff /sbin/sh and /bin/sh?

11. /sbin/sh and /bin/sh

12. /bin/sh .vs. /sbin/sh

13. inetd.conf : 9705 stream tcp nowait root /bin/sh sh -i