Hey There,
I know it's the weekend when I don't get any hate mail regarding posts like yesterday's on producing prime numbers with the bash shell ;)
One truth about prime numbers is that, except for 5, no number ending in 5 can be a prime. Logic dictates that it will, of course, be divisible by itself and by the number 5, thereby removing it from the prime pool. Another thing you may have noticed is the output from the script itself which showed that it found 35 to be a "prime number." It also missed quite a few after 19 (23, 29 and 31, to be specific).
There's a reason I let it go; and not just so I'd have something easy to write about on a "Lazy Sunday" ;) I actually tested this script both on an OpenBSD box and Cygwin for Windows (Unfortunately, I have no Unix computers at my disposal on the weekends, but Linux is just as capable an OS). Neither one could get past 19, when listing out primes; both related to the same two basic problems. The two situations that resulted, when trying to determine higher primes, both had to do with my system limitations, so you might have been able to get higher numbers than I did before the script went South on you :)
The first issue is the theorem we used to determine the primes. Since Wilson's Theorem depends on factorial computation in order to determine a number's prime status, each succeeding number requires an additional operation, which make the numbers required to test divisibility grow at an alarming rate.
For instance, the factorials of 2, 3 or 4 are trivial:
2 = 2 * 1 --> Factorial equals 2
3 = 3 * 2 * 1 --> Factorial equals 6
4 = 4 * 3 * 2 * 1 --> Factorial equals 24
and you can see how the numbers can begin to get large very quickly.
The second issue is the capacity of the Linux or Unix operating system to handle extremely large numbers. Although both of my systems are running 32 bit OS's, the 64 bit OS will have to eventually fail as well. On a 32 bit system, the magic number 20 is where the wrap-around occurs and the numbers become so large that the system can misinterpret them as negative something-or-other. Here are my two example outputs (truncated):
For Cygwin on 32 bit XP, you can see this in the script when you invoke bash with the -x flag, as it hits the breaking point at the number 22 (soooo close to 23 ;)
...
+ count=22
+ '[' 22 -le 22 ']'
++ prime_number 22
++ local prime=22
++ p_minus_1=21
+++ factorial 21
+++ local factorial_count=21
+++ '[' 21 -eq 0 ']'
+++ (( factor=20 ))
+++ (( 20 >= 1 ))
+++ factorial_count=420
+++ (( --factor ))
+++ (( 19 >= 1 ))
+++ factorial_count=7980
+++ (( --factor ))
...
+++ (( --factor ))
+++ (( 2 >= 1 ))
+++ factorial_count=-4249290049419214848
...
at this point, the test for divisibility becomes unreliable, at best.
On OpenBSD, 32 bit, the results were exactly the same:
...
+++ (( --factor ))
+++ (( 2 >= 1 ))
+++ factorial_count=-4249290049419214848
...
Naturally, then, every number tested for "prime status" by our prime number shell script, beginning with 22 couldn't be tested correctly, resulting in many more surprising results like 35 ;)
In any event, hopefully, the script helped make at least one method to determine primes more accessible or understandable. As we noted, also, in yesterday's post, no one has been able to define the largest prime number yet. Yesterday's script gives you a pretty clear idea of the reason. When faced with an infinite number of integers, the requirements for calculation, alone, make this an impossible task. But, basically, the reasons all boil down to the same thing (although, if you look around the web, there are a few unprovable - in the absolute sense - theories that claim the number can be known):
The nature of integers is infinite. If you think of the highest number you can and add 1, you're one step closer to being frustrated for the rest of your life ;)
Also, for clarity's sake, since the mathematics in my head don't always match what I type, I thought I'd save you some paraphrasing and just dump two definitions here on the page; for composite numbers and relative primes (with my side-notes and apologies):
Relative Primes: The integers a and b are relatively prime if they have no common factor other than 1 or, equivalently, if their greatest common divisor is 1 (Note that this was correctly defined yesterday, but not thoroughly enough, since I didn't mention the fact that, although the numbers can't be primes and must have the greatest common factor of 1, I neglected to mention that neither pair of numbers could have any other common factors. A fairly large distinction, but lost in the mix when I was typing. For instance, 6 and 35 are relative primes, while 6 and 36 aren't, since they both share a common factor of being divisible by 3. ...My mind can be a terrible thing ;)
Composite Numbers: These are any positive integers which have a positive divisor other than one or themselves (While these can be derived by multiplying any two prime numbers, which I pointed out, the less complicated definition is that composite numbers are any number that isn't a prime. The multiplication of any 2 primes to create a composite is more of a cool little frill than a necessity. It's a lot easier to wrap your head around when you look at it that way ;)
But, as promised, with regards to composites , we won't put a script out, so much as a description of a method, since the same mathematical boundaries would be hit performing this operation:
1. Run yesterday's script, or pick up a prime number table that will start with 2; the first real prime (check out yesterday's post on producing prime numbers for the reasons 1 and 0 aren't considered primes).
2. Remove every number in the prime table from the larger set of all numbers.
Voila: You have all of the composite numbers, although you will most probably never ever find them all ;)
Here's to another month or so of non-math-related posts ;)
Cheers,
, Mike
Sunday, June 15, 2008
Shell Scripting, Factorial Primes And Huge Number Computations On Linux And Unix
Tuesday, June 3, 2008
More Recognition For Readers' Suggested Improvements On Earlier Scripts
Hey There,
Today, I thought we'd take some time out to recognize folks on all the different boards and networking sites who've made excellent suggestions for improvement on some of the shell/Perl scripts and one-liners we've put out here over time (We've posted these before, usually in the form of updates to previous posts, which may or may not get any more attention than this, but the suggestions for improvement were welcomed warmly, and instated gladly, as they are today).
Firstly, I'll comment on the "no-comment" policy of this blog. It has nothing to do with conflict avoidance, as we check the boards regularly and have, even before this, made significant changes to posts based on user feedback. The problem is with the place that hosts our blog (guess? ;) and comment-spam. It was determined, after enabling it for a few days a few months ago, that we were getting slaughtered with CAPTCHA-savvy spam posts about various "escort" services, which directly conflicted with our insistence that the blog contained absolutely no "adult" content.
It was decided, instead to create a forum where people could sign up and leave remarks. But, even though it's still around, that still seems a little too close to opt-in mailing list tactics, and we wanted people to be able to comment without fear of having their information sold or used by any third-party hosting the forum (although I don't believe they do this as I never receive any mail from them about anything ;)
The next step was to plaster our main email (eggi@comcast.net) on every script so that any user could email us, and any spammer could spam us, without it causing a problem with the blog host. We also check "talkbacks" and comments from posts of our posts on other sites whenever we get the chance.
With that in mind, we'll get on to the first suggested improvement made by folks via email and on the boards over at linuxtoday.com, LXer.com and fsdaily.com (There are others out there, that we'll be giving propers to, and, hopefully, for those remaining out there, we'll find them eventually, also :). Since our policy regarding privacy is to regard everyone's privacy as sacrosanct, no names will be mentioned unless specifically requested, and if nicknames and/or screen-names have been used in "talkbacks" we'll only indirectly refer to them by referring back to the original "talkbacks" which are already out there.
Our first improvement was brought to our attention via email regarding our post on using the bash shell to send mail. While, the systems we tested on worked well with the published script, this alteration made the program work more consistently and reliably on a number of different flavours of Linux (while maintaining on the already-tested versions), including Cygwin for Windows:
exec 9<>/dev/tcp/$mailserver/25
echo "HELO $domain" >&9
was changed to add an additional "read" in case the file-descriptor buffer backed up and needed to be flushed of the initial mailserver connect message, so that the following HELO would get picked up okay and the script wouldn't sprint ahead of itself.
exec 9<>/dev/tcp/$mailserver/25
read -r temp <&9
echo "$temp"
echo "HELO $domain" >&9
and, near the final part of the script, where the data gets sent, the script was modified from:
cat $mailtext >&9
echo "." >&9
read -r temp <&9
to
cat $mailtext >&9
echo -e ".\r" >&9
read -r temp <&9
since Cygwin (for one) wasn't accepting the single line "dot" finale with a standard echo newline.
It should also be noted that this problem could not be fixed on a number of Linux and Unix flavours, since the default bash file system did not come with the /dev/tcp and /dev/udp pseudo-filesystem compiled in. I believe Ubuntu is one such distro. And, they're not doing anything "wrong" by not including it by default. Technically, although it's fun to goof with, this functionality raises some legitimate security concerns.
Over the course of the next few posts (interrupted by more spurts of semi-original thought ;), we'll be posting other significant suggestions and improvements.
And we'll end today's post with a big "Thank you" to anyone and everyone who's helpful criticism has added fresh perspective to this blog and, more significantly, provided better help for the folks who use it as a place to stop by and dig on some useful information :)
Cheers,
, Mike
Sunday, May 11, 2008
Fun Using Banner To Send Subliminal Messages In Cygwin Linux
Greetings, once again,
Here's a good "Lazy Sunday Post" in the same vein as previous posts on using color in the shell and the like. Much like a psychic reading, this post is for entertainment purposes only ;)
Today, I put together a little no-variable script (from which a real script could easily grow) using the "banner" command in Cygwin Linux. It's very simple to use and takes no arguments at all. You can execute it simply, like this:
hot # ./subanner <--- If there were arguments they might be "what your banner says" and "what you really mean" ;)
I didn't bother putting in any error checking, either, since this is just for a goof and doesn't take any variables. This works well on any implementation of the "banner" command that accepts the -c flag to indicate what character the banner should be printed out with. If your distro of Unix or Linux doesn't have this capability, Perl has a Text::Banner module that can do the same thing.
Hope you have fun mucking with this (make it your own. We all have something unique to say ;) and, at the same time, let users that log on to your machines know what you really think :)
p.s. If anyone knows how to strip the ending \012 off of banner output (And I've tried octal dump, sed, awk, tr, hex and octal codes, Perl, etc), please email me - it's making me nuts ;) Therefore, this banner is vertical rather than horizontal.
Maybe if it wasn't the weekend my brain would be in better shape to tackle this issue ;)
Cheers,
This work is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License#!/bin/bash
#
# subanner - subliminal banner :)
#
# 2008 - Mike Golvach - eggi@comcast.net
#
# Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License
#
message="Be Kind"
meaning="Go Away"
count=0
while [ $count -lt ${#message} ]
do
banner -c "${meaning:$count:1}" "${message:$count:1}"
let count=$count+1
done
, Mike
linux unix internet technology
Wednesday, April 9, 2008
Shell Menu Script For Cygwin Linux To Access The XP Control Panel

Please click the above image for a larger, and scarier, version ;)
Hello again,
Just in case you read the title and thought "oh man, more color?", I've kept it to a minimum here ;) Although the concepts used in creating today's script were covered in our previous posts on using color in the shell and creating a simple color menu (both for Linux and Unix), this one is just different enough that I thought it might be of interest to some folks out there.
Today's script is actually for a very specific brand of Linux: Cygwin for Windows XP (I think you could get away with using this script letter-for-letter on Windows 2000, but I can't be sure about ME and Vista).
The script interface is designed so that you can access the Windows Control Panel directly from your default Cygwin Bash shell. Check out the picture above for a look at it in action (breathtaking... ;). Unfortunately, I have yet to figure out how to make Cygwin control the Control Panel applets once they've launched in Windows. I believe it might be possible with some Tk button pushing, but that's beyond where I'm at with Cygwin.
The script can be run simply from the command line and requires no arguments (Although it does assume that your Windows environment is setup correctly and your system knows where its system32 folder is):
user@hostpc ~ ./xpcpanel.sh
You'll note that not every single control panel option is included in our Linux menu shell script. I picked the top 16 (This is a subjective rating system of course ;). All of the other applets should be listed under your main Windows directory, in the system32 folder and named something like "applet.cpl". For instance, the output from an "ls" on my machine comes out to around 30 applets. They can all be run using the "control" command, like so:
user@hostpc ~ control main.cpl
And here's the complete list of applets you can use to customize this menu (The number and availability may vary depending on your system, but this should be a fair representation. Also note that /cygdrive/c/WINDOWS/system32 directory is actually C:\WINDOWS\system32 if you use Windows to navigate):
user@hostpc ~
$ ls /cygdrive/c/WINDOWS/system32/*.cpl
/cygdrive/c/WINDOWS/system32/access.cpl
/cygdrive/c/WINDOWS/system32/appwiz.cpl
/cygdrive/c/WINDOWS/system32/bthprops.cpl
/cygdrive/c/WINDOWS/system32/desk.cpl
/cygdrive/c/WINDOWS/system32/firewall.cpl
/cygdrive/c/WINDOWS/system32/hdwwiz.cpl
/cygdrive/c/WINDOWS/system32/inetcpl.cpl
/cygdrive/c/WINDOWS/system32/infocardcpl.cpl
/cygdrive/c/WINDOWS/system32/intl.cpl
/cygdrive/c/WINDOWS/system32/irprops.cpl
/cygdrive/c/WINDOWS/system32/javacpl.cpl
/cygdrive/c/WINDOWS/system32/joy.cpl
/cygdrive/c/WINDOWS/system32/main.cpl
/cygdrive/c/WINDOWS/system32/mlcfg32.cpl
/cygdrive/c/WINDOWS/system32/mmsys.cpl
/cygdrive/c/WINDOWS/system32/nCredps.cpl
/cygdrive/c/WINDOWS/system32/ncpa.cpl
/cygdrive/c/WINDOWS/system32/netsetup.cpl
/cygdrive/c/WINDOWS/system32/nusrmgr.cpl
/cygdrive/c/WINDOWS/system32/nwc.cpl
/cygdrive/c/WINDOWS/system32/odbccp32.cpl
/cygdrive/c/WINDOWS/system32/powercfg.cpl
/cygdrive/c/WINDOWS/system32/sapcacpl.cpl
/cygdrive/c/WINDOWS/system32/sapfcpl.cpl
/cygdrive/c/WINDOWS/system32/sysdm.cpl
/cygdrive/c/WINDOWS/system32/telephon.cpl
/cygdrive/c/WINDOWS/system32/timedate.cpl
/cygdrive/c/WINDOWS/system32/wgpocpl.cpl
/cygdrive/c/WINDOWS/system32/wscui.cpl
/cygdrive/c/WINDOWS/system32/wuaucpl.cpl
And here it is. I hope you enjoy it and find it useful. Once I'm on the Linux command line, I don't want to futz around with Windows unless I have to, and this script helps out a little :)
And, oh yes, note also that this is a fairly long menu (16 control panel items alone), so the default Cygwin window won't be big enough to fit it all in. As long as you enter a value (it can even be bogus) and hit any key, it will redraw the screen so you can resize your window as many times as you want)
Cheers,
This work is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License#!/bin/bash
#
# xpcpanel.sh - Save Yourself The Hassle Of Dealing With The XP Start Menu :)
#
# 2008 - Mike Golvach - eggi@comcast.net
# Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License
#
trap 'tput reset;exit 1' 1 2 3 9 15
tput civis
while :
do
echo -e "\033[44;37;22m"
clear
echo -e "\033[41;37m"
echo -ne "\033[46;30m"
tput cup 8 25 ; echo -n " Windows XP Control Panel "
tput cup 9 25 ; echo -n "----------------------------"
tput cup 10 25 ; echo -n " Choose Your Option "
echo -e "\033[40;32m"
tput cup 12 25 ; echo -n " 1. Accessibility "
tput cup 13 25 ; echo -n " 2. Add/Remove Programs "
tput cup 14 25 ; echo -n " 3. Display Settings "
tput cup 15 25 ; echo -n " 4. Add Hardware "
tput cup 16 25 ; echo -n " 5. Internet Explorer Setup "
tput cup 17 25 ; echo -n " 6. Regional Settings "
tput cup 18 25 ; echo -n " 7. Game Controllers "
tput cup 19 25 ; echo -n " 8. Mouse Settings "
tput cup 20 25 ; echo -n " 9. Keyboard Settings "
tput cup 21 25 ; echo -n " 10. Sound/Audio Settings "
tput cup 22 25 ; echo -n " 11. Network Settings "
tput cup 23 25 ; echo -n " 12. User Account Settings "
tput cup 24 25 ; echo -n " 13. Power Settings "
tput cup 25 25 ; echo -n " 14. System Properties "
tput cup 26 25 ; echo -n " 15. Phone And Modem Options"
tput cup 27 25 ; echo -n " 16. Date/Time Settings "
tput cup 28 25 ; echo -n " 17. Quit "
echo -ne "\033[41;30m"
tput cup 30 28 ; echo -n " Pick Your Poison: "
tput cup 30 48
tput sc
read y
tput cup 32 30
case "$y" in
1)
control access.cpl
tput rc
echo -n "Any Key To Menu"
read x
;;
2)
control appwiz.cpl
tput rc
echo -n "Any Key To Menu"
read x
;;
3)
control desk.cpl
tput rc
echo -n "Any Key To Menu"
read x
;;
4)
control hdwwiz.cpl
tput rc
echo -n "Any Key To Menu"
read x
;;
5)
control inetcpl.cpl
tput rc
echo -n "Any Key To Menu"
read x
;;
6)
control intl.cpl
tput rc
echo -n "Any Key To Menu"
read x
;;
7)
control joy.cpl
tput rc
echo -n "Any Key To Menu"
read x
;;
8)
control main.cpl
tput rc
echo -n "Any Key To Menu"
read x
;;
9)
control main.cpl,@1
tput rc
echo -n "Any Key To Menu"
read x
;;
10)
control mmsys.cpl
tput rc
echo -n "Any Key To Menu"
read x
;;
11)
control ncpa.cpl
tput rc
echo -n "Any Key To Menu"
read x
;;
12)
control nusrmgr.cpl
tput rc
echo -n "Any Key To Menu"
read x
;;
13)
control powercfg.cpl
tput rc
echo -n "Any Key To Menu"
read x
;;
14)
control sysdm.cpl
tput rc
echo -n "Any Key To Menu"
read x
;;
15)
control telephon.cpl
tput rc
echo -n "Any Key To Menu"
read x
;;
16)
control timedate.cpl
tput rc
echo -n "Any Key To Menu"
read x
;;
17|q|Q)
tput sgr0
clear
exit
;;
[A-Za-z])
tput cup 32 28
echo "Unless you're quitting, please Pick a NUMBER"
tput rc
echo -n "Any Key To Menu"
read x
;;
*)
tput cup 32 28
echo "$y - Unknown Option"
tput rc
echo -n "Any Key To Menu"
read x
;;
esac
done
, Mike
linux unix internet technology





