Reputation: 685
I was trying to read from the STDIN file descriptor in /dev/fd/0
This is what I wrote, I just want to print every command I ever type on the command shell. I wrote this in Perl but its not good enough:
#!/usr/bin/perl
use strict;
use warnings;
open my $fh, "<", "/dev/fd/0" or die "bububububu";
while (<$fh>) {
print $_."\n";
}
close $fh;
So it doesn't print anything although it gets stuck. Does anyone know how to do it??? If this is not possible can I put all the commands in a file and then read them from the '0' file handle somehow. I just want to capture every command which goes through to the system.
Example file:
#!/usr/bin/perl
use strict;
use warnings;
system("./.file2");
and then file2 is:
echo this is hard!!!
So I want my program to run the first file. When I read the '0' filehandle, I wish to store all the lines run in an array somehow.
MAJOR EDIT: I THINK YOU MISUNDERSTOOD ME. I KNOW ABOUT STDIN AND HOW IT WORKS. THE THING IS I DON'T WANT THE SCRIPT TO READ FOR INPUTS FROM THE STDIN. I WANT THE SCRIPT TO READ FROM WHAT I TYPE IN THE SHELL PROMPT. SO LETS SAY I RUN THE FILE AND THEN I OPEN ANOTHER TEMINAL AND THEN I TYPE THE COMMANDS IN THE TERMINAL. I WANT THE SCRIPT TO RECOGNIZE THOSE LINES AND SAVE THEM IN AN ARRAY.
Upvotes: 0
Views: 2440
Reputation: 73
ban, I don't think what you are trying to do will work. The /dev/fd/0
handle is different for each process (when you open it you basically make a copy/dup of the fh
inherited by the parent process), so the file handle you open in perl will NOT be the same as for your bash.
I believe you have (at least) two options here, though:
while( <STDIN> )
approach, then store them to your file AND pass them to system()
or $qx()
to be executed by a shell, however, since this starts a shell for every command this only works for simple applications. You could work around this by opening a shell in a sub-child and connecting its STDIN/STDOUT filehandles with perl file handles you pipe new commands on and read out their input, though. See perldoc perlopentut
(section Pipe Opens) and/or IPC::Open2
(http://search.cpan.org/~rjbs/perl-5.18.0/ext/IPC-Open3/lib/IPC/Open2.pm) for details. Combined with Term::ReadLine
you can emulate the full input method of a shell and won't notice much of a difference, while logging all commands.~/.bash_history
, and you can access it with `history.If your application is security related, and you are trying to log everything that for instance root
does on a system, then you might want to look into sudo
, also.
Hope this helps you, Christian
Upvotes: 2
Reputation: 13792
There is a special Perl file descriptor associated to standar input. You can rewrite your code as:
use strict;
use warnings;
while( <STDIN> ) {
print;
last if /^QUIT/; #Exit loop if QUIT was typed
}
#<-- Note: no open neither close
Upvotes: 0