LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 09-20-2002, 06:19 AM   #1
acid_kewpie
Moderator
 
Registered: Jun 2001
Location: UK
Distribution: Gentoo, RHEL, Fedora, Centos
Posts: 43,398

Rep: Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965
unescaping a carriage return in perl


I need to get some info out of MPlayer, namely the stdout line that shows the current position and sync of the file and such like. Now, the thing is that this line (from looking at the c source code) terminates in a carriage return ( \r ) which results in a very handy output of this line just overwriting the last, rather than churning out screen after screen of the same info.

so now the problem comes when i wish to read it in from a perl open command, as the line doesn't come into view for me, all those eding in \n are naturally fine, but i don't get the carriage return lines, which is what i want!

Any suggestions?
 
Old 09-20-2002, 09:25 AM   #2
TheLinuxDuck
Member
 
Registered: Sep 2002
Location: Tulsa, OK
Distribution: Slack, baby!
Posts: 349

Rep: Reputation: 33
There are two ways of which I can think to solve this problem.

1. Alter the line input seperator ($/) so that is is a carriage return, instead of a newline.
Code:
{ local $/ = "\r";
   while(<IN>) {
      print $_, "\n";
   }
}
This works, but could be a problem, depending on any other data being read from the input stream, since <FH> depends on $/ for determining it's seperation point (and is used by readline and chomp, as well (Programming Perl 3rd Edition p. 666)).

2. split the input at the carriage returns.

Code:
while(<IN>) {
  chomp;
  my(@return) = split(/\r/, $_);
  print "@return\n";  
}
This will give you an array of the items read in until the first available newline.. this method works nicely, but only if the input stream isn't dumping out a whole lot of data without newlines.. if it's pushing alot of data before sending a newline, you're going to have a large array and not alot of use for it.

I am thinking that #1 will work best for you. My advice would be to only set $/ to "\r" at the very point of the code that you will be reading such a line from the input stream, and set it back to "\n" once you're done. This will allow you to also read normal lines of data from the input stream, if the need is there.

I hope this helps!

TLD
 
Old 09-20-2002, 10:12 AM   #3
acid_kewpie
Moderator
 
Registered: Jun 2001
Location: UK
Distribution: Gentoo, RHEL, Fedora, Centos
Posts: 43,398

Original Poster
Rep: Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965
ahh that's great, i'd just got the same solution from someone in irc, using the second method... work's great now. actually i was just abuot to change the post entirely for a new problem...

I'm trying to handle signals better, as i need to force mencoder to exit cleanly before my script closes, so i have:
Code:
$SIG{'INT'}  = sub { 
  if ($main::mencpid > 0) { kill 'INT', $main::mencpid; }
  die "BYE, Mencpid was $main::mencpid\n";
  exit 0;
};
BUT this only works correctly if i comment out BOTH the die and exit commands? i presume i really should have somje sort of exit command in there, but it stops the kill working correctly. any help? thanks.
 
Old 09-20-2002, 10:26 AM   #4
TheLinuxDuck
Member
 
Registered: Sep 2002
Location: Tulsa, OK
Distribution: Slack, baby!
Posts: 349

Rep: Reputation: 33
First, the exit is unnecessary with die, because the die will terminate the script.

I don't know much about signal handling, so I would personally try to find a way to do so without using them. (=

How is mencoder started?
 
Old 09-20-2002, 10:33 AM   #5
acid_kewpie
Moderator
 
Registered: Jun 2001
Location: UK
Distribution: Gentoo, RHEL, Fedora, Centos
Posts: 43,398

Original Poster
Rep: Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965
well i open it in an open command and pipe the output through a function. there's no other way to stop the program, but i need it to exit correctly as i need to ensure it builds the AVI index (mencoder is a dvd encoding program ICYDK), if it stops instantly, the files are pretty useless.

i had die and exit as they normally seem to be there in peoples examples. maybe exit is just a backup incase the die fails? that's guessing it's even possible for a die to fail...

the source is still at http://thirtythreeandathird.net/mrip/mrip but i guess i just leave it the way it is, without the die or anything...
 
Old 09-20-2002, 11:26 AM   #6
TheLinuxDuck
Member
 
Registered: Sep 2002
Location: Tulsa, OK
Distribution: Slack, baby!
Posts: 349

Rep: Reputation: 33
I'm assuming that the section in question is the:
Code:
my $cmd = "mencoder -ovc lavc -lavcopts $LAVC  -oac mp3lame" .
" -lameopts $BR:br=128 -dvd $track_no $AID -o $FILE $VOP 2>
 /dev/null |";
print "$0 - Running: $cmd\n";
$main::mencpid = open(ARSE, $cmd)
:section, right?

And pretty much, you just need to loop/wait until it is finished, right? So, when:
Code:
while (<ARSE>)
{
  print "$_\n";
  /Pos:\s+(\d+\.\d)s\s+(\d*)f\s+\(\s*(\d+)%\)\s+(\d+)fps\sTrem:\s+(\d+)min\s+(\d+)mb/;
  print "$1, $2, $3, $4, $5, $6\r\n";
}
:stops receiving data, shouldn't that indicate that the program is done? So, why not simply say:
Code:
while (<ARSE>)
{
  print "$_\n";
  /Pos:\s+(\d+\.\d)s\s+(\d*)f\s+\(\s*(\d+)%\)\s+(\d+)fps\sTrem:\s+(\d+)min\s+(\d+)mb/;
  print "$1, $2, $3, $4, $5, $6\r\n";
}
close(ARSE);
After all, if it stops outputting and exits that loop, doesn't that mean the program is done doing it's job, and it's safe to exit?

I have a feeling I'm missing something.... (=

Last edited by TheLinuxDuck; 09-20-2002 at 11:28 AM.
 
Old 09-20-2002, 11:55 AM   #7
acid_kewpie
Moderator
 
Registered: Jun 2001
Location: UK
Distribution: Gentoo, RHEL, Fedora, Centos
Posts: 43,398

Original Poster
Rep: Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965
well no, it's a case of when the perl script is abnormally terminated, it instantly whips the carpet out from underneath mencoder, and doesn't let it tie up it's ends properly, which is essential, so i need to catch the CtrlC signal, and pass it through to mencoder properly. Anyway, that seems to be working, if a little odd. now i kill mencoder OR die depencding on wether mencpid has a value, ok for now i guess...

Brings me to yet another issue. I feel dumb asking these questions, but i guess the questions are reasonable!

so... how do i know if an open command acutally worked? my line
Code:
open (TITLE_INFO, "title_info $main::DVD_DEVICE 2> /dev/null | ") or die "error running title_info! is it on your path?\n";
doesn't work at all, and the program only dies when the lack of output falls through to somewhere else.... i know i can it from a system or such, but $? doesn't work for open.
 
Old 09-20-2002, 12:42 PM   #8
TheLinuxDuck
Member
 
Registered: Sep 2002
Location: Tulsa, OK
Distribution: Slack, baby!
Posts: 349

Rep: Reputation: 33
Quote:
Originally posted by acid_kewpie
so i need to catch the CtrlC signal, and pass it through to mencoder properly.
Ok, that makes sense.. so, if your perl script traps Ctrl C, then why not just have the trapped sub set a global var, something like (untested):
Code:
my($stopped) = "no";
$SIG{INT} = sub { $stopped = "yes" };
$SIG{QUIT} = sub { $stopped = "yes" };
...
...
while (<ARSE> && $stopped ne "yes")
{
  print "$_\n";
  /Pos:\s+(\d+\.\d)s\s+(\d*)f\s+\(\s*(\d+)%\)\s+(\d+)fps\sTrem:\s+(\d+)min\s+(\d+)mb/;
  print "$1, $2, $3, $4, $5, $6\r\n";
}
close(ARSE);
I don't know if this would work, but it's a thought.. also, another thought might be to simply disable Ctrl-C'ing and such..

Quote:
Brings me to yet another issue. I feel dumb asking these questions, but i guess the questions are reasonable!
Don't feel dumb! How in the work are you supposed to learn anything if you don't ever ask questions?

Quote:

so... how do i know if an open command acutally worked? my line
Code:
open (TITLE_INFO, "title_info $main::DVD_DEVICE 2> /dev/null | ") or die "error running title_info! is it on your path?\n";
doesn't work at all, and the program only dies when the lack of output falls through to somewhere else.... i know i can it from a system or such, but $? doesn't work for open.
The 'or' in that line indicates that if the open fails, whatever follows is to be executed. So, if that open fails, the die will be processed. You can tell in the die, though, why it failed if you include a $!, which is the typical error message default variable for perl..

Code:
open (TITLE_INFO, "title_info $main::DVD_DEVICE 2> /dev/null | ") or
    die "error running title_info: $!: is it on your path?\n";
If it's not hitting the die statement, then the open was successful, and the error lies elsewhere.
 
Old 09-20-2002, 12:57 PM   #9
acid_kewpie
Moderator
 
Registered: Jun 2001
Location: UK
Distribution: Gentoo, RHEL, Fedora, Centos
Posts: 43,398

Original Poster
Rep: Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965
well if i make the command deliberately wrong, e.g. try to run title_infoI_REALLY_LIKE_DOUGHNUTS instead, nothing different happens, with || OR or...

oh yeah, sorry about my variable names... i still think it's better that crappy foobar *shudder, i just use my favourite words. as for your suggestion for the while condition, well that will exit that section, however the prblem lies in sending a signal to the child process itself, not handling the output. i'm happy enough with what i've got for now though... thanks
 
Old 09-20-2002, 02:14 PM   #10
acid_kewpie
Moderator
 
Registered: Jun 2001
Location: UK
Distribution: Gentoo, RHEL, Fedora, Centos
Posts: 43,398

Original Poster
Rep: Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965
AHHHHHHHH yes... the stderr redirection blocks the signals!! works fine without it....
 
Old 09-20-2002, 02:20 PM   #11
acid_kewpie
Moderator
 
Registered: Jun 2001
Location: UK
Distribution: Gentoo, RHEL, Fedora, Centos
Posts: 43,398

Original Poster
Rep: Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965Reputation: 1965
but now i have stderr popping out where i don't want it... bum

ohh fixed that to. nothign to reply to!

Last edited by acid_kewpie; 09-20-2002 at 02:30 PM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
grep detecting carriage return, how ? Grafbak Programming 22 01-13-2010 01:19 PM
Find & Replace Carriage Return in ooo linuxian Linux - Software 1 04-09-2005 05:43 PM
carriage return in emac lisp balloon Programming 1 11-23-2004 08:29 AM
Inserting a carriage return in awk legtester Linux - General 1 08-17-2003 05:29 PM
pppd...carriage return?!? icyfire Linux - Software 1 02-14-2002 07:07 AM


All times are GMT -5. The time now is 07:56 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration