The macosxhints Forums

The macosxhints Forums (http://hintsforums.macworld.com/index.php)
-   UNIX - General (http://hintsforums.macworld.com/forumdisplay.php?f=16)
-   -   if string contains? (http://hintsforums.macworld.com/showthread.php?t=90151)

gsprague 05-28-2008 04:20 PM

if string contains?
 
Hello All,

I am trying to write a shell that will verify if a user's entry of an IP address is valid. Not sure if a grep, if, or case statement is the way to go with this.

This will work for the dot and octect count:
MYIP='10.1.1.100'
case $MYIP in
*.*.*.*) echo contains a valid dot and Octect count ;;
*) echo does not contain a valid dot or Octect count ;;
esac

But if there are more than 3 numbers per octect or a non numeric any where then this will still pass.

Any ideas?

Thanks in advance!

baf 05-28-2008 05:35 PM

try this:
Code:

#! /bin/bash
shopt -s extglob

t(){
    [[ ${IP[$1]} -gt 255 ]] && return 0 #ERR
    return 1 # OK
}

MYIP='100.1.1.100'
if [[ $MYIP != +([0-9]).+([0-9]).+([0-9]).+([0-9]) ]] ; then
    echo wrong
else
    IFS=.
    IP=($MYIP)
    if t 0 || t 1 || t 2 || t 3 ; then
        echo wrong2
    else
        echo All OK
    fi
fi

It should check that you have num . num . num . num and that num is less then 256

gsprague 05-28-2008 05:49 PM

baf,

Awesome works like a charm!! Thank you very much! I didn't even think of "greater than". What exactly is shopt -s extglob for?

Thanks again!

baf 05-28-2008 05:58 PM

extglob If set, the extended pattern matching features described
above under Pathname Expansion are enabled.

and the one I wanted is
+(pattern-list)
Matches one or more occurrences of the given patterns

Hal Itosis 05-29-2008 09:03 AM

Here's an awk implementation I whipped up,
as a stand-alone script...
Code:


#!/bin/bash
echo "$1" |
/usr/bin/awk -F. '{
        if (NF != 4) exit 1
        if ($0 ~ /[^0-9.]/) exit 2
        for (i=1; i<5; i++) if ($i > 255) exit 3
}'
exit $?

Seems to work, so far.
Status returned is...
  • 0 = good
  • 1 = too many or too few fields
  • 2 = bad character in input
  • 3 = field value over 255

Or
, as an embedded function (also skipping separate exit statuses
and full awk pathname, for a skosh more reduction) like so...
Code:


okIP () {
        echo "$1" | awk -F. '{
                if (NF != 4 || $0 ~ /[^0-9.]/) exit 1
                for (i=1; i<5; i++) if ($i > 255) exit 1
        }'
        return $?
}

if okIP "$var"; then # etc.

There's probably some way to do it with Perl
that only uses sixteen bytes or something. ;)
[i'd almost expect this is in some library.]

-HI-

baf 05-29-2008 03:44 PM

Raw (unreadable) perl solution without any extra lib
Code:

#!/usr/bin/perl
@o=($ARGV[0].".")=~/\G(\d+)\./gc;exit 1 if @o!=4||$';map{exit 1 if $_>255||/^0\d/}@o;

It's 103 characters And it also rejects attempts like 01.2.3.4

It could also be done with Data::Validate::IP but that got slightly longer because the name is long and I installed it in /opt/local/bin/perl so the hashbang line was longer.

But I can't get near 16 characters :D

Hal Itosis 05-29-2008 10:45 PM

Quote:

Originally Posted by baf (Post 473082)
And it also rejects attempts like 01.2.3.4

I was wondering if leading zeros should be nixed.
Now I see they should: http://070.042.185.231/
won't load macosxhints.

Oh well, back to the drawking board.
103 characters... hmmmm.
(mine's already over 128, without leading-zero handling. :mad: )

;)

nice Perl script btw.

Are we counting spaces, tabs and newlines? :D
[i s'pose so]

Mikey-San 05-30-2008 12:22 AM

Quote:

Oh well, back to the drawking board.
I C what you sed there.

baf 05-30-2008 03:52 AM

Here is a bash script that rejects leading zeros.
Code:

#! /bin/bash -O extglob

t(){
    [[ ${IP[$1]} == 0[0-9]* ]] || [[ ${IP[$1]} -gt 255 ]] || return 1 #OK
    return 0 # ERR
}

I=$1.
if [[ $I != +(+([0-9]).) ]] ; then
    echo wrong
else
    IFS=.
    IP=($1)
    if [[ ${#IP[*]} != 4 ]] || t 0 || t 1 || t 2 || t 3 ; then
        echo wrong2
    else
        echo All OK
    fi
fi


gsprague 05-30-2008 10:46 AM

Hal and Baf,

Thank you very much! Now I have the pleasure of trying to get these to work in a do shell script.

Thanks again!

baf 05-30-2008 01:05 PM

Hal do you really mean that
Code:

.00000000..
is a valip IP address ?
Code:

okIP .00000000.. && echo OK
gives OK

Or even worse
okIP ... && echo OK

Also says ok.

Oh and the reason that leading zeros gives problems is that they are taken as "octal marker"
so try:
ping 070.042.185.231
PING 070.042.185.231 (56.34.185.231): 56 data bytes
it really goes to 56.34.185.231 instead so it could be allowed but then we would have to check like [0-7] instead if a group had a leading zero.....

cwtnospam 05-30-2008 03:30 PM

Quote:

Originally Posted by gsprague (Post 473230)
Hal and Baf,

Thank you very much! Now I have the pleasure of trying to get these to work in a do shell script.

Create a shell script, then use the path to that shell script in your do shell script:

Code:

do shell script "/path/to/yourscriptname.sh " & ipaddress_variable

Hal Itosis 05-30-2008 04:46 PM

Quote:

Originally Posted by baf (Post 473255)
Hal do you really mean that
Code:

.00000000..
is a valip IP address ?

:rolleyes: Sure... about as much as you (and your first script) did.


Quote:

Originally Posted by baf (Post 473255)
Oh and the reason that leading zeros gives problems is that they are taken as "octal marker"

That would imply the sixteen octets:
00, 01, 02, 03, 04, 05, 06, 07, 000, 001, 002, 003, 004, 005, 006, and 007
are all valid (in a sense).

Why then do you reject them? ;)

baf 05-30-2008 05:29 PM

Quote:

Originally Posted by Hal Itosis (Post 473289)
:rolleyes: Sure... about as much as you (and your first script) did.

Well my first script rejected those.


Quote:

Originally Posted by Hal Itosis (Post 473289)
That would imply the sixteen octets:
00, 01, 02, 03, 04, 05, 06, 07, 000, 001, 002, 003, 004, 005, 006, and 007
are all valid (in a sense).

Why then do you reject them? ;)

Because it was easier :D But the really annoying thing is that things like 070.042.185.231 sometimes works as decimal at least in my firefox and ssh.
And sometimes octal like that ping example.....
Hmm wonder if that behavior is defined somewhere :confused:. And to muddle the waters even more.
ping 9999 is obviously allowed goes to (0.0.39.15) but not ssh 9999

so I think we should say that those scripts are to check for a dotted decimal ipv4 address without leading zeros. Concurred?

baf 05-30-2008 05:46 PM

According to this wikipedia article it should even be allowed to give an address like 192.0x00.0002.235 but I would prefer not to have to deal with that. So ssh at least does it wrong. I'm not sure what to say about firefox because there it's in an url and not directly an ipv4 address.

baf 05-30-2008 05:49 PM

Quote:

Originally Posted by Hal Itosis (Post 473161)
Now I see they should: http://070.042.185.231/
won't load macosxhints.

By the way where did that address fail? Browser or what?

ganbustein 05-31-2008 04:11 AM

Quote:

Originally Posted by baf (Post 473309)
According to this wikipedia article it should even be allowed to give an address like 192.0x00.0002.235 but I would prefer not to have to deal with that. So ssh at least does it wrong. I'm not sure what to say about firefox because there it's in an url and not directly an ipv4 address.

Not according to the RFCs.

RFC 997 (Internet Numbers) gives as an example:
Quote:

One commonly used notation for internet host addresses divides the
32-bit address into four 8-bit fields and specifies the value of each
field as a decimal number with the fields separated by periods. This
is called the "dotted decimal" notation. For example, the internet
address of VENERA.ISI.EDU in dotted decimal is 010.001.000.052, or
10.1.0.52.
showing clearly that leading zeroes do not imply octal notation.

As for using a dotted IP address in a URL (for example, in the location field in a web browser), RFC 3986 (URI Generic Syntax) has this to say:

Quote:

7.4. Rare IP Address Formats

Although the URI syntax for IPv4address only allows the common
dotted-decimal form of IPv4 address literal, many implementations
that process URIs make use of platform-dependent system routines,
such as gethostbyname() and inet_aton(), to translate the string
literal to an actual IP address. Unfortunately, such system routines
often allow and process a much larger set of formats than those
described in Section 3.2.2.

For example, many implementations allow dotted forms of three
numbers, wherein the last part is interpreted as a 16-bit quantity
and placed in the right-most two bytes of the network address (e.g.,
a Class B network). Likewise, a dotted form of two numbers means
that the last part is interpreted as a 24-bit quantity and placed in
the right-most three bytes of the network address (Class A), and a
single number (without dots) is interpreted as a 32-bit quantity and
stored directly in the network address. Adding further to the
confusion, some implementations allow each dotted part to be
interpreted as decimal, octal, or hexadecimal, as specified in the C
language (i.e., a leading 0x or 0X implies hexadecimal; a leading 0
implies octal; otherwise, the number is interpreted as decimal).

These additional IP address formats are not allowed in the URI syntax
due to differences between platform implementations. However, they
can become a security concern if an application attempts to filter
access to resources based on the IP address in string literal format.
If this filtering is performed, literals should be converted to
numeric form and filtered based on the numeric value, and not on a
prefix or suffix of the string form.

(Emphasis added)

Remember, it's the RFCs that set the standards, not Wikipedia.

baf 05-31-2008 05:03 AM

Oh I agree with that I was checking what implementations not standards allow. And from rfc3986

Code:

A host identified by an IPv4 literal address is represented in
dotted-decimal notation (a sequence of four decimal numbers in the range 0 to 255, separated by "."),
as described in [RFC1123] by reference to [RFC0952].
Note that other forms of dotted notation may be interpreted on some platforms,
as described in Section 7.4,
but only the dotted-decimal form of four octets is allowed by this grammar.

  IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet

  dec-octet  = DIGIT                ; 0-9
              / %x31-39 DIGIT        ; 10-99
              / "1" 2DIGIT            ; 100-199
              / "2" %x30-34 DIGIT    ; 200-249
              / "25" %x30-35          ; 250-255

The last part to me implies that leading zeros are forbidden in an URI.

Hal Itosis 05-31-2008 12:44 PM

Quote:

Originally Posted by baf (Post 473303)
Well my first script rejected those.

Not on my Mac:
Code:

$ bbbb ".00000000.."
All OK
$ bbbb "..."
All OK

[nice try tho]


Okay, here's my latest stand-alone shell script...
Code:

$ cat okIP
#!/bin/bash
echo "$1" |
awk -F. '{
        if(NF!=4 || $0~/[^0-9.]/) exit 1
        for(i=1;i<5;i++) { if($i>255) exit 2
                if(1>length($i) || length($i)>3) exit 3
                if($i>7 && $i~/^0/) exit 4
        }
}'
exit $?

$ wc okIP
      10      31    192 okIP

Stripping spaces in awk got it down to 192 chars (I left tabs in for sanity's sake).

I'm still not 100% sure if 01.003.05.007 should be allowed, but my rev2 will allow it.
[08 and 009, etc., get rejected]

Your Perl script wins overall (until hayne comes along?), but my Bash beats yours (for now?).

baf 05-31-2008 12:59 PM

No my first script rejects those. If you look in the script the address it checks is IN the script not taken from the commandline. Thats because gspragues:s code was like that.
So you have checked 100.1.1.100 a number of times.

One can also argue if your script really is a bash script or a wrapper for awk. But i'll agree thats it's shorter then my bash script but mine is selfcontained and doesn't use any external processes which usually means a speed gain.
Never mind, the important thing is that we could help the OP and give him several alternatives to work from.
And I did learn some more about IP-addresses which I thought I knew most about already. :rolleyes:

Hal Itosis 05-31-2008 03:18 PM

Quote:

Originally Posted by baf (Post 473457)
No my first script rejects those. If you look in the script the address it checks is IN the script not taken from the commandline. Thats because gspragues:s code was like that. So you have checked 100.1.1.100 a number of times.

Hmm, oh yeah... i never read it closely (just copy/paste/execute).
Okay.



Quote:

Originally Posted by baf (Post 473457)
One can also argue if your script really is a bash script or a wrapper for awk.

I was trying to setup a real #!/usr/bin/awk -f type deal... but I can't seem to figure out
how to get awk to directly apply its pattern processing to a given command-line argument.
Awk is hell-bent on reading files (pathname), and more-than-willing to munch up its stdin.
But forcing it to feed upon command line args (for pattern processing) is nigh impossible.

If anyone here can show me the trick, here's what I have so far...
Code:

#!/usr/bin/awk -f
BEGIN { FS = "." }
{
        if(NF!=4 || $0~/[^0-9.]/) exit 1
        for(i=1;i<5;i++) { if($i>255) exit 2
                if(1>length($i) || length($i)>3) exit 3
                if($i>7 && $i~/^0/) exit 4
}

But, we have to call that version by echoing into it:
echo 12.34.56.78 | okip3

instead of a simple arg:
okip3 12.34.56.78

I tried a bunch of stuff like:
  • - (the dash being an arg symbolizing stdin)
  • "/dev/stdin"
  • ARGV[1]
    and even a here-string:
  • <<<"$1"
Nothing worked. :(

baf 05-31-2008 03:32 PM

Yeah I tried to do that too :mad: and it didn't want to do it for me either.

baf 05-31-2008 03:46 PM

How about this
Code:

#! /usr/bin/awk -F. -f
BEGIN{
    "/bin/echo " ARGV[1] |getline
    if(NF!=4 || $0~/[^0-9.]/) exit 1
    for(i=1;i<5;i++) { if($i>255) exit 2
        if(1>length($i) || length($i)>3) exit 3
        if($i>7 && $i~/^0/) exit 4
    }
}

:D

baf 05-31-2008 04:21 PM

Oh and a new perl version:

Code:

baf@bengt-arne-fjellners-computer ~
$ cat ttt.pl
#!/usr/bin/perl
@o=$ARGV[0]=~/\G(\d+)(?:\.|$)/gc;
exit 1 if @o!=4;
map{exit 1 if $_>255||/^0\d/}@o

baf@bengt-arne-fjellners-computer ~
$ wc -c ttt.pl
      99 ttt.pl

:D

Hal Itosis 05-31-2008 06:59 PM

Quote:

Originally Posted by baf (Post 473499)
#! /usr/bin/awk -F. -f
BEGIN{
"/bin/echo " ARGV[1] |getline

:D

Yeah, that looks about like what it would take. [i'll test it in a minute... thanks!!!]
I think from reading various docs that variations of awk (such as gawk and mawk)
may have that type of kluge condensed into a single option... but not awk itself.

Though I forgot to mention it, I did play around with some (of the eight) variations
of getline... but didn't hit upon the magic you found. I note that -- in addition to that
line you added -- the "GNU Awk User's Guide" seems to suggest that such code should
be shortly followed by:
close("/bin/echo ")

so -- all in all -- it costs almost 50 extra chars, just to read the darn argument. :D

I'll need to run some tests to be sure... maybe it was that "close()" part that prevented
my attempts from working.

Thanks again.

Quote:

Originally Posted by baf (Post 473499)
Code:

baf@bengt-arne-fjellners-computer ~
$ cat ttt.pl
#!/usr/bin/perl
@o=$ARGV[0]=~/\G(\d+)(?:\.|$)/gc;
exit 1 if @o!=4;
map{exit 1 if $_>255||/^0\d/}@o

baf@bengt-arne-fjellners-computer ~
$ wc -c ttt.pl
      99 ttt.pl


99? :eek: That's sick.

baf 05-31-2008 07:08 PM

And I could make it some 4 or 5 characters shorter IF I totally gave up readability. No newlines and some less spaces but thats going too far. I'm very happy to get below 100 chars (even if it's JUST below).

Hal Itosis 05-31-2008 07:26 PM

Quote:

Originally Posted by baf (Post 473534)
And I could make it some 4 or 5 characters shorter
IF I totally gave up readability.

:rolleyes: Oh but, we wouldn't want to do that.
After all... "readability" is Perl's strong point! :D :D :D

baf 05-31-2008 07:35 PM

I totally agree with that. Ones I wrote a program. Went to lunch. Came back and almost wondered "who wrote this? What does it mean?" :D :D :D

Oh and to use close in awk you have to use the exact same sequence of characters as when you opened it. So for:
"/bin/echo " ARGV[1] |getline
You would have to do:
close("/bin/echo " ARGV[1])
so that's even more characters....


Tip: variables!!

C="/bin/echo " ARGV[1]
C |getline
close(C)

And if someone else wants to use that trick and have more code then you should really do:
delete ARGV[1]
otherwise awk will try to read the file 10.1.1.10 or whatever....

I have tested this and it really seems to close the pipe when it should.
Hmm readability what does that mean :D:D

Hal Itosis 06-01-2008 02:09 AM

Quote:

Originally Posted by baf (Post 473545)
Oh and to use close in awk you have to use the exact same sequence of characters as when you opened it. So for:
"/bin/echo " ARGV[1] |getline
You would have to do:
close("/bin/echo " ARGV[1])
so that's even more characters....

As luck would have it, I was just returning to post about precisely that:
The built-in "echo " will do just fine thanks! We needn't bother with /bin,
when Bash (or any shell I imagine) has its own internal echo mechanism.

[or am i mistakenly ignoring scenarios where scripts run sans a terminal?
doesn't matter... right... or ?]

-

BTW, I learned that my previous attempts with "echo " ARGV[1] |getline had failed
because I was doing that part inside BEGIN { }... and then trying to use that read
line inside a second set of { braces }. awk doesn't preserve that 'got line' across
to the next group of braces (it seems).

Also... since your version works *without* close(), I think it's okay to skip that part.
Not sure but -- since awk doesn't send an error about it -- i think it's fine to leave it out.
Or wait...
Quote:

I have tested this and it really seems to close the pipe when it should.
Can you explain that part a little? [sounds like maybe close() is a Good Thing™ to do.]

--

Finally, what is the final consensus about leading zeros in terms of a little tool like
the one we have been building. Is it appropriate for our tool to reject *all* leading
zero attempts? Or perhaps should we allow just the 000 thru 007 range (like i did),
or should we allow *all* leading zero fields (as long as no other violation occurs),
with a philosophy that: well... the user must know what they want if they do that.

Whaddya think? :confused:

baf 06-01-2008 02:28 AM

Use this code:
Code:

#! /usr/bin/awk -F. -f
BEGIN{
    C="/bin/echo " ARGV[1]
    delete ARGV[1]
    C |getline
    #close(C)
    if(NF!=4 || $0~/[^0-9.]/) exit 1
    for(i=1;i<5;i++) { if($i>255) exit 2
        if(1>length($i) || length($i)>3) exit 3
        if($i>7 && $i~/^0/) exit 4
    }
}
{ exit 0 }

and call it as:
xxxx 10.1.1.10 -
(don't miss that hyphen and for this it must be /bin/echo) Now it doesn't terminate until you press enter. In another terminal/window do:
ps axco command |grep echo
And you will find a running echo process
press enter and it dies.
Now remove the comment mark before "close" and repeat.
No extra process. That's what I mean. But really in a short program like this it isn't needed but it's good practise to always use it. In a bigger program if you don't do close and later do echo again (with the same parameters) it would "reuse" the same process and fail. Also you could have a bunch of unnecessary processes.

ganbustein 06-01-2008 03:15 AM

Quote:

Originally Posted by baf (Post 473504)
Oh and a new perl version:

Code:

$ wc -c ttt.pl
      99 ttt.pl


Not too shabby, but you fail to reject trailing periods. How about:

Code:

ronk@sexy:bin(0)$ cat ipok
#!/usr/bin/perl
$_=$ARGV[0];s/[1-9]\d*/$&<256?0:1/ge;exit($_ ne"0.0.0.0");
ronk@sexy:bin(0)$ ipok 1.2.3.4
ronk@sexy:bin(0)$ ipok 1.2.3.4.
ronk@sexy:bin(1)$ ttt.pl 1.2.3.4
ronk@sexy:bin(0)$ ttt.pl 1.2.3.4.
ronk@sexy:bin(0)$ wc -c ipok
      75 ipok

(The '(0)' or '(1)' you see at the end of my shell prompt is the status from the previous command.)

baf 06-01-2008 03:29 AM

About the new version "OOps"
And about yours "I zink we has a winner"

ganbustein 06-01-2008 04:06 AM

Quote:

Originally Posted by Hal Itosis (Post 473594)
Finally, what is the final consensus about leading zeros in terms of a little tool like
the one we have been building. Is it appropriate for our tool to reject *all* leading zero attempts?

I think it depends on what the user is planning to do with an IP address that passes.

I did a search through all the RFCs, looking for every occurrence of the word "dotted". The RFCs seem to be unanimous, in that IPv4 addresses are dotted decimal, while IPv6 addresses are always hex. Typical phraseology, repeated over and over again in the RFCs, is something like:

Quote:

We noted that the getipnodebyname() function must allow the name
argument to be either a node name or a literal address string (i.e.,
a dotted-decimal IPv4 address or an IPv6 hex address).
Several of the RFCs give the IP address of VENERA.ISI.EDU as an example, showing it with and without leading zeroes, but it remains decimal (not octal) even with leading zeroes. (The actual address does change over time. It was apparently originally on the 10.x.x.x subnet, which is no longer world-routable.) I think the purpose of the example is to show that it's OK to pad the address to a fixed width so that printed tables will format nicely.

However, when an IP address is used as part of a URI, they're emphatically opposed to the notion that any reasonable format will do. One issue is the lack of standardization: some sites will interpret a leading zero to mean octal, and others will treat it still as decimal. That means that the same exact URI means different things at different hosts, making routing a nightmare. (Yeah, yeah, different DNS servers might map the same FQDN to different IP addresses, but at least they all agree about which FQDN they're mapping.) Worse, some sites will interpret a leading 0x to mean hexadecimal, while others will interpret the non-digit to mean it's not a numeric address at all, and try to resolve it as a Fully Qualified Domain Name.

All of which leads to some hairy security issues. The use of non-canonical dotted IP addresses (dotted octal, dotted hex, dotted decimal with leading zeroes) opens up some potential attack vectors.

It seems to me to be best to nip the problem in the bud by rejecting non-canonical IP address outright. The worst that will happen is that our subroutine rejects it as an IP address, forcing the caller to look it up using DNS, and that search will probably fail. (If it really could be interpreted as an IP address, its Top Level Domain will be invalid. None of the extant TLDs are numeric or begin with 0x.)

A case could be made for allowing the leading zeroes in situations where you know the string is intended to be an IP address... except that I can't think of many such situations. Utilities like ping will happily accept domain name in lieu of an IP address. The only places I can think of where it has to be an IP address is in specifying a Domain Name Server, or in configuring your local system. In both of those cases, it's not onerous to require the user to use a canonical IP address.

And besides, the octal/decimal ambiguity is enough to make me think that a person prepending extra zeroes in an IP address does not know what they're doing. Are they even aware of the ambiguity? Can they be certain how the address will be interpreted? If so, how? If not, why are they doing it?

baf 06-01-2008 04:55 AM

Quote:

Originally Posted by baf (Post 473399)
Oh I agree with that I was checking what implementations not standards allow. And from rfc3986

Code:

A host identified by an IPv4 literal address is represented in
dotted-decimal notation (a sequence of four decimal numbers in the range 0 to 255, separated by "."),
as described in [RFC1123] by reference to [RFC0952].
Note that other forms of dotted notation may be interpreted on some platforms,
as described in Section 7.4,
but only the dotted-decimal form of four octets is allowed by this grammar.

  IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet

  dec-octet  = DIGIT                ; 0-9
              / %x31-39 DIGIT        ; 10-99
              / "1" 2DIGIT            ; 100-199
              / "2" %x30-34 DIGIT    ; 200-249
              / "25" %x30-35          ; 250-255

The last part to me implies that leading zeros are forbidden in an URI.

I still read this part of rfc3986 as forbidding leading zeros in an uri/url concur? oppose?

Hal Itosis 06-01-2008 05:05 PM

Quote:

Originally Posted by baf (Post 473595)
Use this code [ . . . ] and call it as:
xxxx 10.1.1.10 -
(don't miss that hyphen and for this it must be /bin/echo)
Now it doesn't terminate until you press enter.
In another terminal/window do:
ps axco command |grep echo
And you will find a running echo process
press enter and it dies.
Now remove the comment mark before "close" and repeat.
No extra process. That's what I mean.

But really in a short program like this it isn't needed but it's good practise to always use it. In a bigger program if you don't do close and later do echo again (with the same parameters) it would "reuse" the same process and fail. Also you could have a bunch of unnecessary processes.

Great explanation Bengt... it helped a lot.
Working through the first part, I looked at the process status in more detail:
Code:

$ ps axcru |sed -E '1p;/.*(awk|echo)/!d'
USER      PID %CPU %MEM      VSZ    RSS  TT  STAT STARTED      TIME COMMAND
halito  34294  0.0  0.0  599804    536 s001  S+    2:32PM  0:00.00 awk
halito  34295  0.0  0.0        0      0 s001  Z+    2:32PM  0:00.00 (echo)

There it shows awk as sleeping, and "(echo)" as zombied!

As you mentioned, in this little script -- where we bail out virtually as soon as we "BEGIN" -- and
also make no further attempts to access that process/pipe... we can omit explicitly stating all the
close and delete business. Super. Thanks for making it more understandable.



Quote:

Originally Posted by ganbustein (Post 473601)
How about:
Code:

$ cat ipok
#!/usr/bin/perl
$_=$ARGV[0];s/[1-9]\d*/$&<256?0:1/ge;exit($_ ne"0.0.0.0");
$ wc -c ipok
      75 ipok


WOW! That is "sexy". (impressively so)



Quote:

Originally Posted by ganbustein (Post 473611)
I did a search through all the RFCs . . .

I won't quote the entire text there, but every word was much appreciated.
Thanks for weighing in again.

Being that it makes more sense to either reject all or accept all leading-zero cases,
I therefore removed the awk line which accepted leading zeros on numbers less than 8.
[indeed, such code behavior could more easily cause confusion than add convenience.]

I tried to reduce things a bit more, by not calling length() repeatedly.

So here then is my (unsexy, 200-character) latest version:
Code:

#!/usr/bin/awk -F. -f
BEGIN {
        "echo " ARGV[1] |getline
        if(NF!=4 || $0~/[^0-9.]/) exit 1
        for(x=1;x<5;x++) { y=length($x)
                if($x>255) exit 2
                if(1>y || y>3) exit 3
                if(y>1 && $x~/^0/) exit 4
        }
}


Hal Itosis 06-01-2008 05:42 PM

Quote:

Originally Posted by baf (Post 473614)
I still read this part of rfc3986 as forbidding leading zeros in an uri/url concur? oppose?

Finder didn't seem to complain (when doing a ⌘K on my LAN).
Typing afp://192.168.001.010/ in the server address field
(plus a password) brings up a message saying
"Connecting to afp://192.168.001.010/"
:)

It worked. [though netstat still shows it as 192.168.1.10]


All times are GMT -5. The time now is 05:46 PM.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2014, vBulletin Solutions, Inc.
Site design © IDG Consumer & SMB; individuals retain copyright of their postings
but consent to the possible use of their material in other areas of IDG Consumer & SMB.