blazar has asked for the wisdom of the Perl Monks concerning the following question:

I'm writing a program to transfer some logs to another machine for further analysis on that machine (this is not questionable).

Now the problem is that the logs' filenames contain ehm... a '>' sign. Now, up to this very moment we had not had any substantial problem with this, apart that it is a PITA whenever one has to manually peek into one of those logs and systematically forgets to quote them (because he's using C&P from the output of some other program).

But now a much more serious problem arose, probably due to the fact that I'm using Net::SCP to transfer the files and that this module is only a wrapper around scp. Please note that I say so because I succeed in transferring files with "normal" names whereas I can't get around those damned logs either using them literally or (adopting the dirty workaround of) quoting that '>'.

The relevant portions of code are:

my $scp=Net::SCP->new( { host => 'the_real_host', user => 'the_real_user', interactive => 0, cwd => '/path/to/somewhere' } ); # ... (my $quoted=$_) =~ s/>/\\>/; if ( $scp->put($quoted) ) { # if ( $scp->put($_) ) { # etc
Do you have any suggestion about alternative {modules,strategies} to use? Also, it's not something I ask for, generally, but could you supply some ready-made minimal examples?

PS: desperately looking for a workaround to this embarassing situation I'm thinking of copying them to a temporary, "human-named" file before transferring them.

PS2: we have already cursed the author of the logs-writing program and its behaviour will certainly be fixed in the future, but unfortunately it's not doable soon...

Thank you in advance!

Edit by castaway - changed title from 'Q: re scp'

Replies are listed 'Best First'.
Re: Escaping special characters in filename for Net::SCP
by samizdat (Vicar) on Mar 25, 2005 at 18:22 UTC
    blazar, I've been bitten by various things in non-UN!X filenames SAMBA'd or transferred to UN!X a number of times, and there are two strategies that usually work, though I can't say if they'll solve your current situation:
    1. use "'" . $filename . "'"
    2. use "'./" . $filename . "'"

    HTH!
      I've been bitten by various things in non-UN!X filenames SAMBA'd or transferred to UN!X
      This is not my case, but I'll try what you suggest as well. This must be next week, however.

      Incidentally I "can't" (for a relaxed meaning of "can't", actually) use 2. as I already have absolute paths.

        Bummer. That's the one that usually takes the prize. However, if the other monk's suggestion that your other system is the one (i.e., NTFS) that's choking, you're OOL and will almost certainly need to change the name in one way or another. Suggest that you go ahead and change the name unless you really want to get to the bottom of it and tell us all why it fubars.
      $scp->put(quotemeta) yields:
      Couldn't transfer `/real/file->name': \/real\/file\-\>name: No such file or directory
      
      $scp->put(qq|'$_'|) yields:
      Couldn't transfer `/real/file->name': bash: -c: line 1: unexpected EOF while looking for matching `''
      bash: -c: line 2: syntax error: unexpected end of file
      lost connection
      
      D'Oh!
        What a gross mess, blazar. Anything other than something like the following is not worth your time:
        use File::Copy; $basedir='/path/to/files'; $foo = $_; $foo =~ s#/#slash#g; $foo =~ s#->#arrow#g; $fubar = "$basedir/$_"; copy($fubar, "$basedir/$foo"); $scp->put("$basedir/$foo"); system('rm', "$basedir/$foo") && die "Can't remove $foo:$!\n";
        with appropriate my's and stricts as appropriate.
Re: Escaping special characters in filename for Net::SCP
by sh1tn (Priest) on Mar 25, 2005 at 18:29 UTC
    As far as the remote sshd machine is NT It seems impossible filename creation:
    " The following are the illegal NTFS characters: " / \ * ? < > | :
    Which does not mean that these chars cannot be replaced with valid ones.


      If I'm sanitizing strings, I typically just replace everything that I don't like with an underscore:

      s/[^a-zA-Z0-9.\-]/_/g;

      Please note -- I specifically deal with a negated class that contains the acceptable characters, rather than trying to maintain a list of which potentially bad characters I might have to deal with, to ensure that I don't miss anything that might be bad.

      If you had to ensure the process was reversable in the future, I'd use something similar to URI encoding. (although probably not URI encoding, as I don't trust % normally.)

      Nope. Linux 2 Linux. And that's not the actual problem which appearently lies in some shell interaction as explained some more in detail in another node of this thread. TY in any case...
Re: Escaping special characters in filename for Net::SCP
by thekestrel (Friar) on Mar 25, 2005 at 18:35 UTC
    Hi
    I know this is not the same as quoting correctly to get the module to accept the name, but...If you are wanting to retain the '>' in the name have you considered replacing it with &gt as you would in HTML code? '&' is not an invalid character and you could just interpret the name at the other end? ie. silly>name.doc -> silly&gtname.doc
    Just a thought...

    Regards Paul.
Re: Escaping special characters in filename for Net::SCP
by BUU (Prior) on Mar 25, 2005 at 22:28 UTC
    I'm not sure why escaping the right bracket thingy isn't working for you, but just as a better method of escaping, perl has the quotemeta function which automatically escapes characters like that.
      The funny thing is I do know full well about quotemeta. For some reason it must have seemed better to me to roll my own s/// instead. Anyway "it doesn't work", for the following acceptation of "doesn't work": "No such file".

      OTOH if I do not quote, perl doesn't complain but I get only an empty file on the server, named after what follows '>' in the original filename.