Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask

cvs wrapper with ssh-agent

by jacques (Priest)
on Sep 19, 2008 at 15:02 UTC ( #712535=sourcecode: print w/replies, xml ) Need Help??
Category: Utility scripts
Author/Contact Info jacques
Description: I wrote this cvs wrapper because we were using cvs over ssh and I didn't want to keep logging in each time I invoked cvs. If you are doing the same thing, you might find it useful. One thing to note is that if someone has root, it is possible for them to get your password, since ssh-agent keeps it unencrypted in memory.
# Add the next 2 lines to bash_profile/bashrc file: 
#  eval `ssh-agent` > /dev/null
#  alias cvs='/path/to/'

use strict;
use warnings;
use Expect;
#$Expect::Exp_Internal = 1;
#$Expect::Debug = 3;

my $testcommand = Expect->spawn("ssh-add -l");

if ($testcommand->expect(1, '-re' => 'agent has')) {


    print "CVS Wrapper\n===========\n\n";


        use Term::ReadKey;

        ReadMode 2;

        print "Enter cvs passwd:";

        my $passwd = <STDIN>;
        chomp $passwd;

        ReadMode 0;
        unless (length $passwd > 4) {
              print "\nBad password\n";
             redo GET_PASSWD;

        my $user = $ENV{'USER'};
        my $home = $ENV{'HOME'};
        my $remoteserv = '';
        my $login = "$user" . '@' . "$remoteserv";

        unless (-e "$home/.ssh/") {
        # Set up private keys
        my $command = Expect->spawn("ssh-keygen -t dsa");
        if ($command->expect(2, '-re' => 'Enter')) {
            print $command "\r"; 
        if ($command->expect(2, '-re' => 'passphrase')) {
            print $command "$passwd\r"; 

        if ($command->expect(2, '-re' => 'same')) {
            print $command "$passwd\r"; 

        my $copy_command = Expect->spawn("scp ~/.ssh/ $remot
        if ($copy_command->expect(2, "password")) {
            print $copy_command "$passwd\r";
        if ($copy_command->expect(3, '-re' => 'denied')) {
            print "\nBad password\n";
            unlink "$home/.ssh/", "$home/.ssh/id_dsa";
            redo GET_PASSWD;


        my $ssha_command = Expect->spawn("ssh-add");
        if ($ssha_command->expect(2, "passphrase")) {
            print $ssha_command "$passwd\r";
        if ($ssha_command->expect(1,'-re' =>'Bad')) {
            print "\nBad password\n";
            redo GET_PASSWD;

        print "\nLogin successful\n";
    } #end GET_PASSWD
} else { $testcommand->soft_close(); }

open DATA, "/usr/bin/cvs @ARGV |" or die "Couldn't execute program: $!
    while ( defined( my $line = <DATA> ) ) {
        print "$line\n";
close DATA;
Replies are listed 'Best First'.
Re: cvs wrapper with ssh-agent
by blazar (Canon) on Sep 19, 2008 at 18:06 UTC
    open DATA, "/usr/bin/cvs @ARGV |" or die "Couldn't execute program: $! +";

    I personally believe that even if probably it doesn't do any harm here, you should avoid naming your filheandle DATA since it's a predefined perl one. Of course, had you used a lexical instead, there would have been no problem a priori.

    while ( defined( my $line = <DATA> ) ) {

    As a side note: perhaps you know (and perhaps you don't know) that defined is pleonastic there since perl will dwimmily assume it implicitly for you.

    chomp($line); print "$line\n"; } close DATA;

    Sorry, but I'm very tired and I may be missing something obvious. Anyway: why are you doing this? Line ending conversion? Since it's the very last part of your script, you may even be thinking -for once- of using exec instead, couldn't you?

    If you can't understand the incipit, then please check the IPB Campaign.
      Originally I had did not have the open() there and had the last line as:
      print `/usr/bin/cvs @ARGV`;
      But this failed when there were double quotes in the @ARGV. For example if @ARGV contained: commit -m "message goes here" filename_to_commit

      So I used open() instead.

        I personally believe

        If you use open or exec (or system) you can "bypass" the shell by passing a list with more than one element, e.g.:

        open my $data, '-|', '/usr/bin/cvs' => @ARGV or die horribly;
        If you can't understand the incipit, then please check the IPB Campaign.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: sourcecode [id://712535]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (9)
As of 2020-09-29 17:30 GMT
Find Nodes?
    Voting Booth?
    If at first I donít succeed, I Ö

    Results (150 votes). Check out past polls.