Simulate pressing enter key in Perl - perl

I have following perl script which saves the output from the command into a textfile
#!/usr/bin/perl
use warnings;
use strict;
use Term::ANSIColor;
my $cmd_backupset=`ssh user\#ip 'dsmadmc -id=username -password=passwd "q backupset"' >> output.txt`;
open CMD, "|$cmd_backupset" or die "Can not run command $!\n";
print CMD "\n";
close CMD;
The output of output.txt is this:
Text Text Text
...
more... (<ENTER> to continue, 'C' to cancel)
The script is still running in the terminal and when I press enter, the output.txt file gets the extra information. However, I must press enter more than 30 times to get the complete output. Is there a way to automate the script so when the last line in output.txt is more..., it simulates pressing enter?
I have tried with Expect (couldn't get it installed) and with echo -ne '\n'

Most interactive commands, like the one you are using, accept some flag or some command to disable pagination. Sometimes, connecting their stdin stream to something that is not a TTY (e.g. /dev/null) also works.
Just glancing over IBM dsmadmc docs, I see it accepts the option -outfile=save.out. Using it instead of standard shell redirection would probably work in your case.

Related

CMD operations through Perl

Trying to run some commands through perl. One of the command requires to press enter in the middle to complete!
I was first trying with java but failed to do so i thought it's possible in perl but not getting through!
$dir = "C:\\bip_autochain\\scripts";
chdir($dir) or die("Can't change to dir \n");
system("lcm_cli.bat -lcmproperty C:\\pl\\LCMBiar_Import.property");
sleep(5);
system("\n");
The system command highlighted requires to press enter after some time say 5 sec.
My code doesn't serve this purpose.
If you want to send data from your Perl script to a command launched in a subprocess you need to pipe a filehandle in to the program when launching it. Then you wait the required time and send the data using print (or printf).
There is one huge caveat. If the external program opens the console terminal directly for input and does not read from stdin (i.e. to prompt for a password) you may not be able to send the data to the program.
For the standard case where the program reads from stdin:
$dir = "C:\\bip_autochain\\scripts";
chdir($dir) or die("Can't change to dir \n");
open(CMD, "|lcm_cli.bat -lcmproperty C:\\pl\\LCMBiar_Import.property");
# ^
# vertical bar, aka "pipe" symbol
sleep(5);
print CMD "\n";
...
close(CMD); -- when you are done sending data
The pipe symbol at the beginning of the command is a special form of open that sets up the CMD filehandle piped to the command's stdin. This is descibed in the documentation

Perl script interacting with another program's STDIN

I have a Perl script that calls another program with backticks, and checks the output for certain strings. This is running fine.
The problem I have is when the other program fails on what it is doing and waits for user input. It requires the user to press enter twice before quitting the program.
How do I tell my Perl script to press enter twice on this program?
The started command receives the same STDIN and STDERR from your script, just STDOUT is piped to your script.
You could just close your STDIN before running the command and there will be no input source. Reading from STDIN will cause an error and the called command will exit:
close STDIN;
my #slines = `$command`;
This will also void any chance of console input to your script.
Another approach would use IPC::Open2 which allows your script to control STDIN and STDOUT of the command at the same time:
use IPC::Open2;
open2($chld_in, $chld_in, 'some cmd and args');
print $chld_in "\n\n";
close $chld_in;
#slines = <$chld_out>;
close $chld_out;
This script provides the two \n input needed by the command and reads the command output.
You could just pipe them in:
echo "\n\n" | yourcommand

Perl script doesn't open command prompt on running in Windows7

My Perl script doesn't execute at all when I press F5. In fact the command prompt also doesn't appear. Please help me as to what is wrong. The following is the Hello World script.
use 5.010;
use strict;
use warnings;
print "Hello World!\n";
The problem might be that your program runs so quickly that command prompt opens and closes faster than you can see it. To see if that's the case, and fix it if so, you can wait for user input:
print "Press ENTER to quit.\n";
scalar <>;

How to grab the Unix command that I had run using Perl script?

As I am still new to Unix and Perl, I'm finding a simple and direct method to grab the Unix command that I had run using Perl script.
What I know is "history" can track back the commands that I had run, but it is not working in Perl using back ticks history to run it.
I tried to put "history > filename" in vi text editor in a temporary file, use command "source" it, and it works, but command "source" also not working in Perl script using back ticks.
Can anyone guide me about my problems? direct me to correct method to solve my problems? T.T
Thanks.
You can't. Shells (well, bash and tcsh, anyway, your shell might, but probably doesn't, vary) only save command history in interactive mode. Commands run in a subshell by a perl script won't be added to the history file.
This will get the history of commands that were run by the user in interactive mode:
$data_file = "~/.bash_history";
open(DAT, $data_file) || die("Could not open file!");
#fileData = <DAT>;
close(DAT);
foreach $command (#fileData) {
# Do things here.
}
As mentioned by Wobble, though, this history file will not include commands run from a Perl script - you'll have to have the script append the command to a file when it runs it, thus creating it's own history file (or, append it to ~/.bash_history, which will have it share the history file with interactive shells).
If you have access to the perl script (that is, you can change it), you can simply write each command run in the perl script to a chosen text file:
sub run_program
{
my $program = shift;
open PROGS, ">>my-commands.txt", or die $!;
print PROGS $program."\n";
`$program`;
close(PROGS);
}
then just run `run_program($command) every time you wish to run a command in the script.

How can I use vim to edit text from Perl while the script is still running?

I have a Perl script that outputs text. I want to import this text into vim, edit it, save it and then exit. On exit, I want the original Perl script to process the edited file.
E.G. how crontab -e works when you add a new job.
Thanks :)
Sounds like a very plain case to use system to run vim on the filename. That will wait until vim is done, at which point you can go ahead and read the file's new contents.
use File::Temp;
my $fh = new File::Temp();
my $fname = $fh->filename;
print $fh "My Text";
$fh->close();
system($ENV{EDITOR}, $fname);
open $fh, '<', $fname or die "Can't open temp file: $!";
while(<$fh>) { print }
close $fh;
A suggestion: Why don't you grab the source to crontab and see what it does?
Other than that, unwind has your answer.
And I think the way to think about this is:
"Okay, I need a program to write out a file, call vim, then do further processing on the file. So, here's my routine to write the file, here's my routine that calls vim (using system), and here's my routine to do the postprocessing after vim is done. Now I'll lace them all together in my main program, and I'm done!"
You seem to want to pipe the output of your script into vim:
script | vim
And then you want the script to somehow know that Vim is finished and resume. That's not how I/O redirection works. The script has no knowledge of what program its output is being piped into.
You mentioned other programs like crontab and cvs; one thing those have in common is that they invoke the editor themselves. They create temporary files, read the EDITOR or VISUAL environment variables (check the manual for details about how they choose which one), run the given program, and wait for the program to finish. Then they continue running and use the file they specified earlier.
Turns out I've done exactly that in Perl. I created a temporary file (with tempfile), wrote a bunch of text into it, and then used system to invoke the editor on the file. You don't even have to close the file while you run the editor.
Pipe the output to vim - and don't forget the dash at the end.
script.pl | vim -
This will open vim with the contents of the scripts output. Just save it :w filename and exit :q. This isn't how crontab -e works, but it comes close enough in an easy way.
Edit:
I missed this part (or maybe the question was edited afterward):
On exit, I want the original Perl
script to process the edited file.
This isn't the best way to do this, but going with my original answer, this works (if you save the file as file.txt):
perl -le 'print "1234"' | vim - && perl -pe '' file.txt
Just replace the perl commands with your perl commands and it should work. Like I said, this is not the best answer, but it should work.