is there a way to query a server for its OS type in Perl? For example, if I knew that a remote server was running Windows, I might send it a winver from my local machine and get the output to determine which version of Windows it's running. Yet, is there a way to be even more abstract and simply ask "what are you?"
Since CPAN is huge, I was wondering if there were a module that encapsulated this sort of functionality.
If you can get command-line access on the remove server, then you should be able to use %ENV:
jmaney> perl -e 'print "$ENV{OSTYPE}\n";'
linux
Edit: It looks as though the key in Windows (or, at least on Windows 7 on my laptop) is OS. So, unfortunately, the exact solution via %ENV is OS-dependent... You could, however, check to see which of $ENV{OS} or $ENV{OSTYPE} is defined (and if they're both defined, then canonically pick which one you want to use), and proceed accordingly.
There is no foolproof way to do this, but the HTTP Server header -- which the server isn't required to send -- often contains the OS. For example, it may look like this (from Wikipedia):
Server: Apache/1.3.27 (Unix) (Red-Hat/Linux)
The Perl CGI module has an http function that gets the HTTP headers. You could use it like this:
my $server = $q->http('Server');
# Test $server for Windows, *nix, etc
# My Perl experience is minimal and I haven't used it in
# a while, so I'm not going to give an example here, but
# someone can feel free to edit one in.
CPAN probably has a module to do the testing on the Server header for you.
Related
I want to develop an agent (preferably in perl ) for windows , that when requested from other host pass on information to requester host.
Are there any API that can be used to serve above purpose ? Is there any recommended way of doing this.
I want to get some expert comments on it,before actually starting it.
Windows won't be a problem with ActivePerl or Strawberry Perl. You can run your program as a service if you can follow a few easy directions.
When you say "agent" do you mean "network service"? You can use HTTP::Server::Simple to do a basic http-based agent, or if you want to build your own protocol you can always use IO::Socket::INET.
Ultimately it depends on what kind of "agent" you need, and how you want to access the agent.
I have a shell script which archives log files based on the whether the process is running or not. If the log file is not used by the process then I archive it. Until now, I'm using lsof to get the log file being used but in future, I have decided to use perl to do this function.
Is there a perl module similar to what lsof in linux can perform ?
There is a perl module, which wraps around lsof. See Unix::Lsof.
As I see it, the big problem with not using lsof is that one would need to work in a way that is independent of the operating system. Using lsof allows the perl programmer to work with a consistent application allowing for operating system independence.
To have a perl module developer to write lsof would, in effect, be writing lsof as a library and then link that into perl - which is much more work than just using the existing binary.
One could also use the fuser command, which shows the process IDs with the file handle. There is also a module which seeks to implement the same functionality. Note from the perldoc:
The way that this works is highly unlikely to work on any other OS
other than Linux and even then it may not work on other than 2.2.*
kernels.
One might try walking /proc/*/fd and looking at the file descriptors in there to see if any are pointing to the file in question. If it is known what the process ID of a running process that would be opening the log file, it would be just as easy to look at that process. Note, that this is how the fuser module works.
That said, it should be asked "why do you want to move away from lsof"?
I have some programs that use the Net::Telnet module to connect to several servers. Now the administrators have decided to replace the Telnet service for SSH, keeping everything else like before (for example the user accounts)
I've taken a look at Net::SSH2 and I see that I would have to change most part of the programs. Do you know of other SSH modules, better suited for this same replacement?
The client is a Windows box (ActiveState Perl or Cygwin Perl)
Net::OpenSSH!
And check the chapter about how to integrate it with Net::Telnet.
Thanks for your suggestions, but I finally used Net::SSH::Perl on ActivePerl for Windows
Pros:
quite similar to Net::Telnet. There is no close method, but instead of $host->close you can do $host->cmd("exit")
native Perl implementation
Cons:
each cmd() call has a different state, for example it doesn't keep the current directory between calls, like Net::Telnet did
needs a modification in the module code to work on Windows, see: https://rt.cpan.org/Public/Bug/Display.html?id=18154
cmd("su - user") doesn't work, but cmd("su - user -c 'commands'") does
I basically want to be able to send the apache log file line by line (tail) in between two servers (unidirectionally, from one two one), I want to use perl.
Any idea?, I would like be able to do things with each line of apache log in real time but in another server.
Thanks you!
Not sure about Perl (you can probably wrap this up in a bit of Perl so you can manipulate the data), but netcat (or nc for short) (should be available on most systems).
On one server
tail -f filename | nc -l 12345
On the other server
nc hostname 12345
Of course you can use a different port number. So I guess in Perl you would exec these commands (ssh to the remote server etc.). Hopefully this has given you some ideas! nc has loads of options so you should be able to find something.
If you want to write netcat in Perl then that's a slightly different story.
You can use piped logs. This way your perl script will get every log line on standard input and then it's up to you, how you are going to send them (SSH, FTP, HTTP or maybe even connect to SQL etc).
A very simple solution is to tail the log file from the remote host via SFTP using Net::SFTP::Foreign.
The module contains a sample script implementing the remote tail: sftp_tail.pl
I am wondering if anyone has a Perl script (or can write one) to execute on multiple hosts at once via ssh, without any modules. I used to have something like this but cannot find it now and can't remember how it was done.
Are you looking for ClusterSSH? It's Perl, and it's used to run the same commands on several hosts at once, so this might be what you're looking for...
You might want to try using Expect.pm which is similar to #cnicutar's suggestion of calling an Expect script from Perl, except that you write it all in Perl. (This of course down not fit the requirement of "without any modules", but that requirement leads to bad Perl )
Learn how to install and use modules even when you don't have admin privileges on the host
Use Net::OpenSSH::Parallel
If you cannot use any additional modules from CPAN or any other source , all I can recommend you are:
1) Use Expect script and call it internally in your Perl script [Only if you are not willing to use Expect.pm module]
2) Use SSH keygen in all the servers to which you will connect to , so that password wont be necessary in the script. As mentioned by "cnicutar"
3) Use "remsh" if SSH usage is not that necessary.