![]() |
Perl advice needed
I have come across a small Perl script I'd like to use, but haven't got the faintest idea what to do with it. Basically it reports my IP address to my web server should my Mac get stolen.
The script is --- #!/usr/bin/perl sleep int(rand 60); $network = `ifconfig -a inet 2>/dev/null | sed -n -e '/127.0.0.1/d' -e '/0.0.0.0/d' -e '/tunnel/d' -e '/inet/p' | wc -l`; $serial_number1 = `system_profiler 2> /dev/null | grep \"Customer serial number\"`; @serial_number2 = split (' ', $serial_number1); $url = "http://www.iainbroughton.com/$serial_number2[3].html"; $useragent = "Thief Killer (Mac OS X)"; if ( $network == 1 ) { **$status = `curl -A \"$useragent\"$www.iainbroughton.com`; } --- but the resulting output gives me a load more stuff I don't really understand --- #/usr/bin/perl Percy:~ iain$ Percy:~ iain$ sleep int(rand 60); -bash: syntax error near unexpected token `(' Percy:~ iain$ $network = `ifconfig -a inet 2>/dev/null | sed -n -e '/127.0.0.1/d' -e '/0.0.0.0/d' -e '/tunnel/d' -e '/inet/p' | wc -l`; -bash: =: command not found Percy:~ iain$ Percy:~ iain$ $serial_number1 = `system_profiler 2> /dev/null | grep \"Customer serial number\"`; grep: serial: No such file or directory grep: number": No such file or directory -bash: =: command not found Percy:~ iain$ @serial_number2 = split (' ', $serial_number1); -bash: syntax error near unexpected token `(' Percy:~ iain$ $url = "http://www.iainbroughton.com/$serial_number2[3].html"; -bash: =: command not found Percy:~ iain$ $useragent = "Thief Killer (Mac OS X)"; -bash: =: command not found Percy:~ iain$ if ( $network == 1 ) { -bash: syntax error near unexpected token `{' Percy:~ iain$ \302\240\302\240$status = `curl -A \"$useragent\" www.iainbroughton.com`; % Total % Received % Xferd Average Speed Time Curr. Dload Upload Total Current Left Speed 100 5037 100 5037 0 0 1898 0 0:00:02 0:00:02 0:00:00 4127 -bash: **: command not found --- Do I need to compile this script? Do I need to make it executable, what file extension should it have? |
No compilation needed. It's a script, not source code. And it should not just be copied and pasted to the Terminal, because it attempts to run each line individually (as you saw above).
Just copy the code you have into a file and name it whatever you want, with .pl as a suffix. Like foo.pl. Make it executable, thusly: chmod +x foo.pl Then run the executable script thusly: ./foo.pl |
As simple as that? Wow! You guys are Mac GODS!!!
I followed your advice and now I get Scalar found where operator expected at ./test.pl line 13, near "**$status" (Missing operator before $status?) syntax error at ./test.pl line 13, near "**$status " Execution of ./test.pl aborted due to compilation errors. |
The **$status doesn't make any sense in Perl.
It looks like you have some corruption in your copy of the script. |
Quote:
-- sed: option requires an argument -- e usage: sed script [-Ean] [-i extension] [file ...] sed [-an] [-i extension] [-e script] ... [-f script_file] ... [file ...] sh: line 2: /0.0.0.0/d: No such file or directory -- Basically all I want this script to do is to contact my web server with a specific/unique user agent so it is easy to identify the IP that it has come from. Has any one any other ideas for doing this? |
There are some things with the script that don't make sense to me. The **$status is one of them. The use of $www is another.
I found the script with Google, and it looks like Code:
#!/usr/bin/perlHmm. I copied and pasted the source from the page I linked to, and got ** before the $status in this post. Weird. Then posted into a text editor, and noticed that the two characters before the $status were not viewable. So definite weirdness from the copy and paste. And by looking at the source, there are two characters before $status... |
And just to amuse myself, I retyped this into a new file to make sure there were no other strange characters. I changed the script a bit. No reason to store into $status if we don't use it, so I just took it out. Also set the script to use strict, added comments, and removed extraneous variables.
Code:
#!/usr/bin/perl |
OK, I've edited it now to
-#!/usr/bin/perl sleep int(rand 60); $network = `ifconfig -a inet 2>/dev/null | sed -n -e '/127.0.0.1/d' -e '/0.0.0.0/d' -e '/tunnel/d' -e '/inet/p' | wc -l`; $serial_number1 = `system_profiler 2> /dev/null | grep \"Customer serial number\"`; @serial_number2 = split (' ', $serial_number1); $url = "http://www.iainbroughton.com/$serial_number2[3].html"; $useragent = "Thief Killer (Mac OS X)"; if ( $network == 1 ) { $status = `curl -A \"$useragent\" $url`; } -- I still get the same error -- sed: option requires an argument -- e usage: sed script [-Ean] [-i extension] [file ...] sed [-an] [-i extension] [-e script] ... [-f script_file] ... [file ...] sh: line 2: /0.0.0.0/d: No such file or directory -- Still stumped, and what is IP 0.0.0.0 anyway? |
Beware Copy and Paste
Quote:
Looking at the script some more, it looks like it is reporting the IP number as given by ifconfig. If your stolen computer is behind a router, then you are only going to get the private IP address like 192.168.0.X or something just as useless. I think you would be better off getting the outside IP address. There are scripts in the forums that will do that for you, I am using one myself. Let me know if you want and I'll post it. My $.02 |
I've copied and pasted your script and still get
sed: option requires an argument -- e usage: sed script [-Ean] [-i extension] [file ...] sed [-an] [-i extension] [-e script] ... [-f script_file] ... [file ...] sh: line 2: /0.0.0.0/d: No such file or directory Usage: grep [OPTION]... PATTERN [FILE]... Try `grep --help' for more information. sh: line 2: Customer serial number: command not found As for the BBEdit, is that an extra I need to install (yes, still green in the realms of Terminal!) |
Not sure if this is the issue, but make sure that whatever editor you're using isn't trying to break up long lines like:
Code:
my $network = `ifconfig -a inet 2>/dev/null | sed -n -e '/127.0.0.1/d' -e '/0.0.0.0/d' -e '/tunnel/d' -e '/inet/p' | wc -l`; |
Bag it?
OK, let's back up a second and take a look at what we're trying to do here.
You want your computer to post your IP number in case it is stolen, right? 1. What IP number do you want to report? 2. Where is it going to report the number? 3. How often is this going to happen? It looks like this script has some flaws in it. To me, the major one is using the ifconfig command to report the IP number. Because of the router problem I noted earlier, this is not the most useful way to get a valid IP number. For example, if I stole your computer and took it home, plugged it into my network and your script fired, it would report an IP number of 192.168.0.3 or something just as useless to you. You want the OUTSIDE IP number that my router gets from my ISP. The second flaw (or my understanding is flawed here) is that I can't see how this information is posted anywhere. Maybe I am not seeing the whole script? At any rate, I do the same thing you are trying to. I will post a separate set of instructions for that if you want to give it a try. |
Track a changing IP number remotely
Found it!
http://www.macosxhints.com/article.p...MOTE+ip+number It looks like dyndns has changed their page format. This actually makes it simpler. My script now is just: Code:
#! /bin/sh |
derekhed brings up a good point (a while ago, I'm a slow typist today :) ). How are you editing these files?
BBEdit is a text editor, from BareBones software. It's a nice editor, but not free. $179 or so. So if you're using pico in the Terminal, you can either fix the newlines yourself, or modify the script so that it's unlikely to wrap. I find that long lines in pico are a pain in the... script. So I changed the script to use shorter lines. In this version no lines are longer than 56 characters, so unless your Terminal window is really small it shouldn't wrap, and so pico shouldn't introduce any funky newlines that would mess things up: Code:
#!/usr/bin/perl |
Quote:
1. Yes I want an EXTERNAL IP address to be reported. 2. The best thing I can think of (with this script) is to have it access my hosted web server which will record the IP address given and the referal agent (ie even though I am behind a router, it still knows my IP is 212.159.xxx.xxx). If I can create a unique referal agent, so instead of Mozilla/IE/Whatever, it reports "Your Mac is Here" even better. 3.How often ismy Mac going to be stolen? Never (I hope!!). How often will this script run, I don't know, once an hour or even less if I feel paranoid enough! Any instructions that will help secure my Mac are welcome. Yes I know if someone was determined to steal it, then they would, but at least it would give me SOME hope of catching the little b*$****$! |
Quote:
Quote:
It would attempt to download a page with your computer's serial number. That's from the system_profiler command. It doesn't matter if that page even exists on your web server, the logs will show the attempt. And the logs will also have the real IP address. It's actually a clever setup if the person who stole the machine connects it to the net. And also assuming that your webserver is not your home machine. |
I also found an error in the script, but it may just be due to changes in the report generated by system profiler (I'm guessing this script was written on something other than Panther).
The system profiler doesn't report a "Customer Serial Number", just three instances of "Serial Number". So the line Code:
$command .= "grep \" Customer serial number\"";Code:
$command .= "grep -i \"serial number\""; |
Ah, I get it now. Very nice...
I am guessing that by getting your machine's serial number, you can find it in the logs of your web server. I did have a problem with that. I am running 10.3.4 and my system_profiler command returns: Serial Number: WS83N2H5T0 (ok, I made that up) Point is that the text is not "Customer serial number". Plus it takes a looong time. So I would change your grep command to: Code:
$command = "system_profiler -detailLevel -2 2>/dev/null | ";Code:
$command .= "$webserver/$serial_number[2].html";Can you think of any more improvements? (dang! Took too long! Thanks nkuvu!) |
I'm not sure why the serial number has to be generated dynamically. All you're looking for, really, is a unique identifier. I suppose it is a little easier to set up if the script determines the serial number, but since the end user has to change the web server name anyway, why not add the serial number also?
Code:
#!/usr/bin/perl |
On the other hand...
This script did originate from a site dedicated to more cluster and lab oriented solutions, i.e., universities and large organizations. I can imagine the desire to keep a general script around that would work on a large number of machines. Even in my case, I run three Macs and tweaking files for each one has driven me batty in the past. (I'm much better now, thank you.)
I would therefore grep insensitively for 'serial' while using the -detailLevel flag available to the system_profiler command in 10.3. This should avoid the discovery of other serial numbers not associated with the hardware. I don't have access to any 10.2 machines, so I can't test other system_profilers. I suppose you could check for other versions of the profiler in your script... |
Yay!
After all that hard work, it finally does what it is supposed to do. The final code was altered to:-
--- #!/usr/bin/perl use strict; sleep int(rand 60); # Change this to match your server name: my $webserver = "http://www.iainbroughton.com"; # Don't change anything below this unless you know what # you're doing. :) my $command = "ifconfig -a inet 2>/dev/null | "; $command .= "sed -n -e '/127.0.0.1/d' -e '/0.0.0.0/d' "; $command .= "-e '/tunnel/d' -e '/inet/p' | wc -l"; my $network = `$command`; $command = "system_profiler -detailLevel -2 2>/dev/null | "; $command .= "grep -i \"serial number\""; my @serial_number = split ' ', `$command`; if ($network == 1) { $command = "curl -A \"Thief Killer (Mac OS X)\" "; $command .= "$webserver/$serial_number[2].html"; system $command; } --- and now produces a very pretty entry on my server log file (Obviously I've altered the IP and serial for this posting!) -- 212.159.xxx.xxx - - [03/Jul/2004:11:41:13 +0100] "GET /W902103XPJH.html HTTP/1.1" 200 0 "-" "Thief Killer (Mac OS X)" -- Thankyou so much! :) |
The only thing I don't quite understand is the
$command = "system_profiler -detailLevel -2 2>/dev/null | "; $command .= "grep -i \"serial number\"" as it doesn't show up anywhere, and the W902103XPJH.html was created manually by me. Should the serial number (as got automatically by the script) show up anyhere? At least it works though! :) |
If you want to make this less noticeable, you should avoid running the system_profiler when not connected to a network.
To do this, just add the following line right after the line that sets the $network variable. exit unless $network; |
Doesn't show up anywhere?
The script won't create the HTML file, if that's what you're thinking. And really, the HTML file doesn't need to exist in order for this to work. If it doesn't, the log will show a 404 response (instead of the 200 that you quoted) but you'll still have all of the info you need. If you're thinking that the curl command should save the HTML file somewhere, you'd be right. If the command had the proper options. What's happening as it stands is that the curl has a -A option, which sets the user agent. Then it downloads the file and sends it to standard output. If you run this script by itself you'll see the downloaded file displayed on the screen. If you wanted to save the file you'd need to add a -o or -O option to the curl command (read man curl for explanations of the options). |
No, I didn't think it would create the HTML file for me, and no, the system serial number doesn't appear at all. I don't want the file saved locally. Sorry for sounding thick, but I don't really understand what this is doing other than making a stamp (either a 200 or a 404) in my servers log, displaying the correct IP address. Is it actually supposed to show anything up in the HTML file, or just show in the server log? :confused:
|
The point is just to put a stamp in the server log. The HTML file is irrelevant.
|
In which case we have succeeded! :)
|
Quote:
|
Well yes, but I don't have the luxury of a dial up account. I'll just have to take this as a suitable measure untill I can verify it further. I'm quite content with the way that this is working at the moment, I presume the way the script is written, it doesn't matter how the machine is connected to the internet, as long as there is a connection present?
|
Quote:
|
| All times are GMT -5. The time now is 05:45 AM. |
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.