-
Notifications
You must be signed in to change notification settings - Fork 3
/
lo
executable file
·206 lines (188 loc) · 5.45 KB
/
lo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
#!/usr/bin/env perl
$usage = <<EOM;
Usage:
lo . - show all the mappings
lo ls - show all the mappings
lo .show - show all the mappings
lo [host] - login to the specified host
lo [host] = [user\@host.domain] - map host to the given value
lo [host] is - show what host is mapped to
lo [host] auto - automate login to host
lo [host] rm|del - delete the host mapping
lo [host] tcsh - setup host with tcsh and shell scripts
lo [host] com|run [command] - execute command on host
lo [host] / [command] - execute command on host
lo [host] ul [local_path] [remote_path]
- upload to the remote host
rsync -aze ssh [local_path] $remote:[remote_path]
lo [host] dl [remote_path] [local_path]
- download from the remote host
rsync -aze ssh $remote:[remote_path] [local_path]
lo [host] ulx [local] [remote] - same as ul but also delete remote path/file to mirror local
lo [host] dlx [local] [remote] - same as dl but also delete local path/file to mirror remote
lo .keys - show all the ~/.ssh/*.pem files and current one in use
lo [host] key [key_file] - set the key file to use for the specified host
TODO
lo [host_from]:[path] to [host_to]:[path]
transfer the contents of path one host to another
EOM
$host = $ARGV[0];
$action = $ARGV[1];
$value = $ARGV[2];
$arg1 = $ARGV[2];
$arg2 = $ARGV[3];
$arg3 = $ARGV[4];
$home = $ENV{HOME};
$conf = "$home/.lo.hosts";
if (! $host){ die $usage; }
if (($host eq '.show') || ($host eq '.') || ($host eq 'ls')){
print "$conf\n";
if ($action ne ''){
print `cat $conf | grep '.' | grep "$action" | sort`;
}
else{
print `cat $conf | grep '.' | sort`;
}
exit;
}
if ($host eq '.keys'){
print `(cd $home/.ssh/; ls *.pem | sort)`;
exit;
}
# read the host mapping file
%h = readHost();
%k = readKeys();
$remote = $h{$host};
$key = $k{$host};
if ($key){
$keyop = "-i $home/.ssh/$key";
}
$didit = 0;
if ($action eq '='){
if (! $value){
die "Need user\@host.domain\n";
}
$h{$host} = $value;
writeHost(%h);
exit;
}
if ($remote eq ''){
die "$host has no mapping. Try: lo $host = user\@host.domain\n";
}
if ($action eq 'auto'){
if (! -e "$home/.ssh/id_rsa.pub"){
print "if this gets stuck then manually run: ssh-keygen -t rsa\n";
print `ssh-keygen -t rsa`;
}
print "you will be prompted for the remote password twice\n";
`ssh $remote "mkdir -p .ssh; touch .ssh/authorized_keys; chmod go-rwx .ssh/authorized_keys .ssh"`;
`cat ~/.ssh/id_rsa.pub | ssh $remote 'cat >> .ssh/authorized_keys'`;
exit;
}
if ($action eq 'is'){
if ($h{$host}){ print "$h{$host}\n";}
exit;
}
if (($action eq 'rm') || ($action eq 'del')){
delete $h{$host};
writeHost(%h);
exit;
}
if (($action eq 'com') || ($action eq 'run') || ($action eq '/')){
print "$remote\n";
# run the command
$rc = join(' ',@ARGV[2..$#ARGV]);
print `ssh $keyop $remote '$rc'`;
exit;
}
if ($action eq 'tcsh'){
# make sure we have auto first
`rsync -ae ssh $keyop $home/.setup_shell.tgz $remote:`;
print `ssh $keyop $remote 'tar xzpf .setup_shell.tgz'`;
print `ssh $keyop $remote 'chsh -s /bin/tcsh'`;
$didit = 1;
}
if ($action eq 'dl'){
# rsync -ae ssh $keyop $remote:[remote_path] [local_path]
if ($arg1 eq ''){ die "need remote path\n"; }
if ($arg2 eq ''){ $arg2 = '.'; }
if ($arg2 eq '-'){ $arg2 = $arg1; }
print `rsync -aze 'ssh $keyop' $remote:$arg1 $arg2`;
$didit = 1;
}
if ($action eq 'ul'){
# rsync -ae ssh $keyop [local_path] $remote:[remote_path]
if ($arg1 eq ''){ die "need local path\n"; }
if ($arg2 eq '-'){ $arg2 = $arg1; }
print `rsync -aze 'ssh $keyop' $arg1 $remote:$arg2`;
$didit = 1;
}
if ($action eq 'dlx'){
# rsync --delete-after -ae ssh $keyop $remote:[remote_path] [local_path]
if ($arg1 eq ''){ die "need remote path\n"; }
if ($arg2 eq ''){ $arg2 = '.'; }
if ($arg2 eq '-'){ $arg2 = $arg1; }
print `rsync --delete-after -aze 'ssh $keyop' $remote:$arg1 $arg2`;
$didit = 1;
}
if ($action eq 'ulx'){
# rsync --delete-after -ae ssh $keyop [local_path] $remote:[remote_path]
if ($arg1 eq ''){ die "need local path\n"; }
if ($arg2 eq '-'){ $arg2 = $arg1; }
print `rsync --delete-after -aze 'ssh $keyop' $arg1 $remote:$arg2`;
$didit = 1;
}
if ($action eq 'key'){
$k{$host} = $arg1;
writeHost(%h);
$didit = 1;
}
if (! $action){
%h = readHost();
if (! $h{$host}){
die "$host has no mapping. Try: lo $host = user\@host.domain\n";
}
print "ssh $keyop $h{$host}\n";
exec "ssh $keyop $h{$host}";
exit;
}
if (! $didit){
die "No action defined for: $action\n";
}
sub readHost{
my(%h, $fh, $l, $k, $v);
open($fh, "$conf");
foreach $l (<$fh>){
chomp $l;
($k, $v) = ($l =~ m/(\S+) +(\S+)/);
if ($k){ $h{$k} = $v; }
}
close $fh;
return %h;
}
sub readKeys{
my(%h, $fh, $l, $k, $v, $x);
open($fh, "$conf");
foreach $l (<$fh>){
chomp $l;
($k, $x, $v) = ($l =~ m/(\S+) +(\S+) +(\S+)/);
if ($k){ $h{$k} = $v; }
}
close $fh;
return %h;
}
sub writeHost{
my(%h) = @_;
my($fh, $k, $v, $w);
open($fh, ">$conf");
while(($k, $v) = each(%h)){
$w = $k{$k}; # set w to the key assigned to the host
if ($w){
print $fh "$k $v $w\n";
}
else{
print $fh "$k $v\n";
}
}
close $fh;
}