Is there any way to capture the texts on termianl screen inside a perl script. I know there are some functions like system,exec,backticks but the problem is that they execute commands FROM the script.For ex:- in terminal i write cd/ (or) ls,and after that i run my perl script which will read what was written on termianl screen(in this case, scipt will capture cd/ (or) ls-whichever was given to termianl). I came with one solution that by passing the commands which you wrote on termianl as a command line arguments to the script,but any other way???
Like this maybe:
history | perl -ne 'print $_'
As I understand it, in a situation where you've typed some stuff into a terminal like this:
[tai#littlerobot ~] echo "Hello"
Hello
[tai#littlerobot ~] perl myscript.pl
You want myscript.pl to be able to access the echo "Hello" part, and possibly also the Hello that was that command's output.
Perl does not provide such a feature. No programming language does or can provide such a feature because the process in which your script/program runs has no intrinsic knowledge about what happened in the same terminal before it was run. The only way it could access this text would be if it could ask the currently running terminal, which will have some record of this information (i.e. the scrollback buffer), even if it cannot distinguish between which characters in the text were typed by you, and which are output. However, I know of no terminal that exposes that information via any kind of public API.
So if you want myscript.pl to be able to access that echo "Hello", you'll need to pass it to your script. Piping history to your script (as shown by Mark Setchell in his answer) is one technique. history is a shell built-in, so it has as much knowledge as your shell has (which is not quite the same knowledge as your terminal has). In particular it can give you a list of what commands have been typed in this shell session. However, it cannot tell you about the output generated by those commands. And it cannot tell you about other shell sessions, so doing this in Perl is fairly useless:
my #history = `tcsh -c history`;
The last thing you could try (though it would be incredibly complicated to do) would be to ask the X server (or Windows if running on that operating system) for a screen shot and then attempt to locate which rectangle the current terminal is running in and perform OCR on it. This would be fraught with problems though, such as dealing with overlapping windows.
So, in summary, you cannot do this. It's nothing to do with Perl. You cannot do this in any programming language.
Related
I usually think of UNIX pipes as a quick and dirty way to interact with the console, doing things such as:
ls | grep '\.pdf$' #list all pdfs
I understand that it's possible to use create named pipes using mkfifo and mknod.
Are named pipes still used significantly today, or are they a relic of the past?
They are still used, although you might not notice. As a first-class file-system object provided by the operating system, a named pipe can be used by any program, regardless of what language it is written in, that can read and write to the file system for interprocess communication.
Specific to bash (and other shells), process substitution can be implemented using named pipes, and on some platforms that may be how it actually is implemented. The following
command < <( some_other_command )
is roughly identical to
mkfifo named_pipe
some_other_command > named_pipe &
command < named_pipe
and so is useful for things like POSIX-compliant shell code, which does not recognize process substitution.
And it works in the other direction: command > >( some_other_command ) is
mkfifo named_pipe
some_other_command < named_pipe &
command > named_pipe
pianobar, the command line Pandora Radio player, uses a named pipe to provide a mechanism for arbitrary control input. If you want to control Pianobar with another app, such as PianoKeys, you set it up to write command strings to the FIFO file, which piano bar watches for incoming commands.
I wrote a MAMP stack app in college that we used to manage users in an LDAP database on a file server. The PHP scripts would write commands to a FIFO that a shell script running in launchd would read from and interact with the LDAP database. I had no idea what I was doing, so I don’t know if there was a better or more correct way to do it, but it worked great at the time.
Named pipes are useful where a program would expect a path to a file as an argument as opposed to being willing to read/write with stdin and stdout, though very modern versions of bash can get around this with < ( foo ) it is still sometimes useful to have a file like object which is usable as a pipe.
So I am trying run a perl debugger inside another perl debugger. I keep readin tty in perl is the solution. Can someone explain to me what tty means ( is it terminal type?) and how is it useful? This is where I read it:
http://search.cpan.org/~rjbs/perl-5.18.0/lib/perl5db.pl#$CreateTTY
The reason I am trying to use tty is because of this question I asked:
Pass argument to perl file in debugger and set breakpoint in file executed by system
Thanks to all the ones who answer, the more you guys tell me what it is, better the idea I get :)
TTY (short for teletype) is basically a special input or output filehandle that connects to the terminal - namely, user input. For nitty gritty details, see:
Unix.SE in-depth answer on TTYs
Text Terminal HOWTO
This is what you need to know for starters (hard to say more since you didn't explain what you need to do with a TTY):
On Unix, it typically maps to /dev/tty device or similar
You can test for it using -t in Perl
As far as debugger, 2 things need to be known at least (if you intend to play with the TTY, the last paragraph is the most important). All data is near-quoted from perldoc perldebug
p expr prints to $DB::OUT filehandle (NOT STDOUT), which in turn is open to /dev/tty.
I think this may be controlled by LineInfo option from PERLDB_OPTS but never played with it so not sure.
Can be affected by the following $ENV{PERLDB_OPTS} options:
TTY - The TTY to use for debugging I/O.
noTTY - If set, the debugger goes into NonStop mode and will not connect to a TTY. If interrupted (or if control goes to the debugger via explicit setting of $DB::signal or $DB::single from the Perl script), it connects to a TTY specified in the TTY option at startup, or to a tty found at runtime using the Term::Rendezvous module of your choice.
This module should implement a method named new that returns an object with two methods: IN and OUT . These should return filehandles to use for debugging input and output correspondingly. The new method should inspect an argument containing the value of $ENV{PERLDB_NOTTY} at startup, or "$ENV{HOME}/.perldbtty$$" otherwise. This file is not inspected for proper ownership, so security hazards are theoretically possible.
Python offers an interactive interpreter allowing the evaluation of little code snippets by submitting a couple of lines of code to the console. I was wondering if a tool with similar functionality (e.g. including a history accessible with the arrow keys) also exists for Perl?
There seem to be all kinds of solutions out there, but I can't seem to find any good recommendations. I.e. lots of tools are mentioned, but I'm interested in which tools people actually use and why. So, do you have any good recommendations, excluding the standard perl debugging (perl -d -e 1)?
Here are some interesting pages I've had a look at:
a question in the official Perl FAQ
another Stackoverflow question, where the answer mostly is the perl debugger and several links are broken
Perl Console
Perl Shell
perl -d -e 1
Is perfectly suitable, I've been using it for years and years. But if you just can't,
then you can check out Devel::REPL
If your problem with perl -d -e 1 is that it lacks command line history, then you should install Term::ReadLine::Perl which the debugger will use when installed.
Even though this question has plenty of answers, I'll add my two cents on the topic. My approach to the problem is easy if you are a ViM user, but I guess it can be done from other editors as well:
Open your ViM, and type your code. You don't need to save it on any file.
:w !perl for evaluation (:w !COMMAND pipes the buffer to the process obtained by running COMMAND. In this case the mighty perl interpreter!)
Take a look at the output
This approach is good for any interpreted language, not just for Perl.
In the case of Perl it is extremely convenient when you are writing your own modules, since in my experience the perl interpreter will refuse to reload a module (even when loading was attempted and failed). On the minus side, you will loose all your context every time, so if you are doing some heavy or slow operation, you need to save some intermediate results (whilst the perl console approach preserves the previously computed data).
If you just need the evaluation of an expression - which is the other use case for a perl console program - another good alternative is seeing the evaluation out of a perl -e command. It's fast to launch, but you have to deal with escaping (for this thing the $'...' syntax of Bash does the job pretty well.
Just use to get history and arrows:
rlwrap perl -de1
I am new to Perl and I have the following problem.
I have a log output and I have found where this log output comes from. I mean the subroutine in some module that prints it.
Now e.g. in Java via Eclipse I would use e.g. Call hierarchy and other utilities to see how/when/who calls the method and figure out how to reproduce what I need and debug.
How can I do this in Perl? Via e.g. grep? If I grep e.g. for the module name I get hundrends of lines ranging from use A require A C::B::A B::A C::B::A::some_routine C::B::A::some_other_routine etc.
On top of this I am worried that perhaps the routine I am interested in is not called directly but some script e.g. runs the module that is of interest to me via some obscure (to me due to my ignorance in Perl) manner.
So how would I go debug something in Perl in the most efficient way? What do you Perl gurus suggest for me to do and become more efficient?
Run the program under the Perl debugger:
perl -d scriptname arguments...
Set a breakpoint in the function you care about, and when the program stops at the breakpoint use the T debugger command to display a stack trace, which will show where the function was called from.
From your comments, I'm not sure this actually addresses what you're looking for. Maybe what you want is a cross-reference of the Perl application? See the FAQ How do I cross-reference my Perl programs?
Most of the time getting a stack trace (along with some debugging info) is a good start. One can use standard Carp module to generate stack traces:
use Carp;
print_to_log(Carp::longmess("We're here"));
Or there's an object-oriented module for that as well.
To get a dump of the call stack without modifying any code, you can use the perl command line to run your program under Carp::Always:
perl -MCarp::Always my_program.pl
I'm a Perl programmer doing some web application testing using Selenium. I was wondering if there's some kind of interactive interpreter which would allow me to type Selenium commands at a prompt and have them sent to selenium.
The way I'm currently developing code is to type all of the commands into a Perl script, and then execute the script. This make the development process painfully slow, because it makes it necessary to rerun the entire script whenever I make a change.
(If I were a Ruby programmer, I bet the Interactive Ruby Shell could help with this, but I'm hoping to find a solution for Perl.) Thanks!
The Java-based SeleniumServer has an --interactive mode.
I don't know about a Selenium shell, but if you are looking for a Perl REPL, there are modules such as Devel::REPL and Carp::REPL. I've made shells for various simple things using my Polyglot module, although I haven't looked at that in awhile.
May I ask why it's "necessary to re-run the entire script"? Since your solution is an interactive shell, i'm assuming that it's NOT because you need previous commands to set something up. If that's a correct assumption, simply make your set of Selenium commands in Perl script in such a way that you can skip the first N commands.
You can do it by explicit "if" wrappers.
Or you can have a generic "call a Selenium command based on a config hash" driver executed in a loop, and adding the config hash for every single Selenum command to an array of hashes.
Then you can either have an input parameter to the test script that refers to a # in an array; or you can even include unique labels for each test as a part of a config hash and pass "start with test named X" or even "only do test named X" as input on command line.