Hi Ola,

Ola Lundqvist wrote:
> >   RANDOM=$(dd if=/dev/urandom count=1 2> /dev/null | cksum | awk 
> > '{print$1}')
> > 
> > Splitting on whitespace is more resilient to input differences than
> > splitting on each space character.  IMNHO using awk for field
> > selection is almost always better than using cut.  The variations in
> > 'wc' output is a good example of where awk works as desired but cut
> > would not.
> 
> Ah, I see. So if we happend to get a tab here cut would fail. In that case
> Checked it and you are right.
> 
> ola@quartz:~/svn/fsp/cron-apt$ echo "1204231524"$'\t'"512"
> 1204231524                   512
> ola@quartz:~/svn/fsp/cron-apt$ echo "1204231524"$'\t'"512" | awk '{print$1}'
> 1204231524
> ola@quartz:~/svn/fsp/cron-apt$ echo "1204231524"$'\t'"512" | cut -d' ' -f1
> 1204231524                   512
> 
> I think we should use awk as well. Good then I'll do so.

Yes.  This is also just a general style of defensive shell scripting.
For example 'wc' notoriously has different output on different
systems.  On some systems it has leading spaces and on others it does
not.  And having experienced problems with differing whitespace from
various utilities I like to avoid being sensitive to them.

> > Since this has come up for discussion here it gives me an opportunity
> > to cringe once again at using /dev/*random and the unportability of
> > it and perhaps suggest using awk instead.  In my own scripts I have
> > been using portable awk for generating random numbers.  Therefore I
> > would suggest this instead and eliminate the use of /dev/*random.
> > Noting that in Debian this works with either mawk or gawk.
> > 
> >   RANDOM=$(awk -v rs=$RUNSLEEP -v s=$$$(date +%M%S) 
> > 'BEGIN{srand(s);print(int(rs*rand()));}')
> 
> I do not really think this is a good approach. The reason is that you
> initialize the random vector with the same minute and second every day.
> Which means that you will end up in no randomness at all.

Your point about "$(date +%M%S)" being the same because this runs from
cron at the same time every day is a good one and one that I had
missed.  In my application that isn't true but I failed to see that
point when suggesting it here.  My bad.

However that is only half of the seed.  The "$$" is the other part of
the seed value.  That will be different every run.  Each time the
script is run it will get a different process id.

That is why I had originally had both $$ and $(date ...) so that
either one or the other would be different each time.

> > Command line test case:
> > 
> >   $ awk -v rs=3600 -v s=$$$(date +%M%S) 
> > 'BEGIN{srand(s);print(int(rs*rand()));}'
> >   1194
> 
> This is easy to see if you run the above command fast like this:
> ola@quartz:~/svn/fsp/cron-apt$ awk -v rs=3600 -v s=$$$(date +%M%S) 
> 'BEGIN{srand(s);print(int(rs*rand()));}'
> 82
> ola@quartz:~/svn/fsp/cron-apt$ awk -v rs=3600 -v s=$$$(date +%M%S) 
> 'BEGIN{srand(s);print(int(rs*rand()));}'
> 82
> ola@quartz:~/svn/fsp/cron-apt$ awk -v rs=3600 -v s=$$$(date +%M%S) 
> 'BEGIN{srand(s);print(int(rs*rand()));}'
> 555
> ola@quartz:~/svn/fsp/cron-apt$ awk -v rs=3600 -v s=$$$(date +%M%S) 
> 'BEGIN{srand(s);print(int(rs*rand()));}'
> 555

In the command line testing run the $$ is always the same process id.
It is the command shell's process id.  But in a script that part would
always be different.  In normal use in a script the seed would always
be different.

> So thanks for the suggestion, but I'll stick to /dev/*random where
> we know that we will get real random data.

That is fine of course.  :-)

> I can use this variant in case /dev/urandom does not exist...
> Actually I will do that. However I will change +%M%S to +%N to have
> better randomness in it.

Good plan.  GNU date used in Debian includes %N.  But in my application
I need it to run on HP-UX and IBM AIX and neither of those provide %N.

> Changes are uploaded now.

I am sure that whatever you ended up using is fine. :-)

Bob

Attachment: signature.asc
Description: Digital signature

Reply via email to