rubsh 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +0 -0
- data/Manifest +11 -0
- data/README.rdoc +0 -0
- data/Rakefile +10 -0
- data/bin/rubsh +18 -0
- data/lib/alias.rb +19 -0
- data/lib/commands.rb +86 -0
- data/lib/prompt.rb +45 -0
- data/lib/rub_readline.rb +22 -0
- data/lib/rubsh.rb +146 -0
- data/rubsh.gemspec +32 -0
- metadata +77 -0
data/CHANGELOG
ADDED
File without changes
|
data/Manifest
ADDED
data/README.rdoc
ADDED
File without changes
|
data/Rakefile
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'echoe'
|
3
|
+
Echoe.new('rubsh','0.0.1') do |gem|
|
4
|
+
gem.description = 'A ruby shell'
|
5
|
+
gem.url = 'http://github.com/danielb2/rubsh'
|
6
|
+
gem.author = 'Daniel Bretoi'
|
7
|
+
gem.email = 'daniel@netwalk.org'
|
8
|
+
gem.development_dependencies = []
|
9
|
+
end
|
10
|
+
|
data/bin/rubsh
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# http://bogojoker.com/readline/
|
3
|
+
rubsh_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
4
|
+
$LOAD_PATH.unshift(rubsh_dir) unless $LOAD_PATH.include?(rubsh_dir)
|
5
|
+
require 'rubsh'
|
6
|
+
require 'optparse'
|
7
|
+
$DEBUG = false
|
8
|
+
|
9
|
+
def parse_options
|
10
|
+
parser = OptionParser.new()
|
11
|
+
parser.on("--debug", "If included run in DEBUG mode") do
|
12
|
+
$DEBUG = true
|
13
|
+
end
|
14
|
+
parser.banner "rubsh"
|
15
|
+
parser.parse(ARGV)
|
16
|
+
end
|
17
|
+
|
18
|
+
Rubsh.new.run
|
data/lib/alias.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
class Alias
|
2
|
+
@@aliases = Hash.new
|
3
|
+
def self.parse(str)
|
4
|
+
str.scan(/^\s*([^\s]+)(.*)$/) do |name,val|
|
5
|
+
@@aliases[name] = val
|
6
|
+
end
|
7
|
+
end
|
8
|
+
def self.[]=(name,value)
|
9
|
+
@@aliases[name] = value
|
10
|
+
end
|
11
|
+
def self.[](name)
|
12
|
+
@@aliases[name]
|
13
|
+
end
|
14
|
+
def self.show
|
15
|
+
@@aliases.each do |k,v|
|
16
|
+
puts "alias #{k} = #{v}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/commands.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
class Commands
|
2
|
+
@@oldpwd = nil
|
3
|
+
def get_binding
|
4
|
+
binding
|
5
|
+
end
|
6
|
+
|
7
|
+
def help(arg)
|
8
|
+
case arg
|
9
|
+
when /help.*prompt/
|
10
|
+
puts %|
|
11
|
+
%h - hostname
|
12
|
+
%u - the username of the current user
|
13
|
+
%w - the current working directory, with $HOME abbreviated with a tilde
|
14
|
+
%W - the basename of the current working directory, with $HOME abbreviated
|
15
|
+
with a tilde
|
16
|
+
%Cb - blue color
|
17
|
+
%Cc - cyan color
|
18
|
+
%Cg - green color
|
19
|
+
%CC - color reset
|
20
|
+
%t - the current time in 24-hour HH:MM:SS format
|
21
|
+
%% - literal %
|
22
|
+
%$ - if the effective UID is 0, a #, otherwise a $
|
23
|
+
|
24
|
+
Example: ENV['PR1'] = "[%u@%h]--(%t)\\n\\r[%w]%$ "
|
25
|
+
|
|
26
|
+
else
|
27
|
+
puts %|
|
28
|
+
ralias - alias command
|
29
|
+
example: ralias 'ls ls -Gh'
|
30
|
+
aliases ls to 'ls -Gh'
|
31
|
+
|
32
|
+
shortcuts:
|
33
|
+
'...'.ls - shortcut for Dir.glob(...)
|
34
|
+
'...'.ls.du is available to do `du` on the files
|
35
|
+
|
36
|
+
prompt:
|
37
|
+
use ENV['PR1'] to set your prompt.
|
38
|
+
see 'help prompt' for options
|
39
|
+
|
40
|
+
~/.rubsh/rc.rb
|
41
|
+
you can define your aliases, prompt and define
|
42
|
+
your own functions in here.
|
43
|
+
|
44
|
+
commandline functions:
|
45
|
+
* it gets sent it's own invocation
|
46
|
+
* must be a one liner
|
47
|
+
example: def test(*a); p a;end # test foo #=> ["test foo"]
|
48
|
+
|
49
|
+
|
|
50
|
+
end
|
51
|
+
end
|
52
|
+
def cd(dir)
|
53
|
+
dir.gsub! /\s*cd\s*/, ''
|
54
|
+
dir.gsub! /\s*$/, ''
|
55
|
+
dir.gsub! /("|')/, ''
|
56
|
+
if dir.empty?
|
57
|
+
@@oldpwd = Dir.pwd
|
58
|
+
Dir.chdir ENV['HOME']
|
59
|
+
return
|
60
|
+
end
|
61
|
+
|
62
|
+
if dir == '-'
|
63
|
+
if @@oldpwd
|
64
|
+
curdir = Dir.pwd
|
65
|
+
Dir.chdir @@oldpwd
|
66
|
+
@@oldpwd = curdir
|
67
|
+
else
|
68
|
+
puts "OLDPWD not set"
|
69
|
+
end
|
70
|
+
return
|
71
|
+
end
|
72
|
+
|
73
|
+
if dir =~ /^~\/?/
|
74
|
+
dir.gsub!('~',ENV['HOME'])
|
75
|
+
end
|
76
|
+
@@oldpwd = Dir.pwd
|
77
|
+
Dir.chdir dir
|
78
|
+
end
|
79
|
+
def method_missing(m,*args)
|
80
|
+
if ::Rubsh::iscmd? m.to_s
|
81
|
+
system(m.to_s)
|
82
|
+
return
|
83
|
+
end
|
84
|
+
raise "rubsh: #{m}: command not found"
|
85
|
+
end
|
86
|
+
end
|
data/lib/prompt.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
class Prompt
|
2
|
+
def colorize(text, color_code)
|
3
|
+
"#{color_code}#{text}\e[0m"
|
4
|
+
end
|
5
|
+
|
6
|
+
def self.color(color='default')
|
7
|
+
color_map = {
|
8
|
+
'blue' => "\e[34m",
|
9
|
+
'green' => "\e[32m",
|
10
|
+
'cyan' => "\e[36m",
|
11
|
+
'default' => "\e[0m",
|
12
|
+
}
|
13
|
+
return color_map[color] ? color_map[color] : color_map['default']
|
14
|
+
end
|
15
|
+
|
16
|
+
def red_text(text); colorize(text, "\e[31m"); end
|
17
|
+
def magenta_text(text); colorize(text, "\e[35m"); end
|
18
|
+
|
19
|
+
def green_bg(text); colorize(text, "\e[42m"); end
|
20
|
+
|
21
|
+
def self.parse_map
|
22
|
+
return {
|
23
|
+
'%h' => `hostname -s`.chomp,
|
24
|
+
'%d' => Time.now.strftime('%d'),
|
25
|
+
'%u' => Etc.getpwuid.name,
|
26
|
+
'%w' => Dir.pwd.gsub(ENV['HOME'],'~'),
|
27
|
+
'%W' => File.basename(Dir.pwd.gsub(ENV['HOME'],'~')),
|
28
|
+
'%Cb' => color('blue'),
|
29
|
+
'%Cc' => color('cyan'),
|
30
|
+
'%Cg' => color('green'),
|
31
|
+
'%CC' => color,
|
32
|
+
'%t' => Time.now.strftime('%H:%M:%S'),
|
33
|
+
'%%' => '%',
|
34
|
+
'%$' => Process.euid == 0 ? '#' : '$'
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.parse(str)
|
39
|
+
str = str.dup
|
40
|
+
parse_map.each do |key,value|
|
41
|
+
str.gsub!(key,value)
|
42
|
+
end
|
43
|
+
return str
|
44
|
+
end
|
45
|
+
end
|
data/lib/rub_readline.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'readline'
|
2
|
+
Readline.completion_proc = Proc.new do |str|
|
3
|
+
Dir[str+'*'].
|
4
|
+
grep( /^#{Regexp.escape(str)}/ ). #only return dirs which start with str
|
5
|
+
map { |f| f =~ /\s/ ? "\"#{f}\"" : f } # if names have spaces, then quote
|
6
|
+
#Dir[str+'*'].select { |f| File.stat(f).executable? }.grep( /^#{Regexp.escape(str)}/ )
|
7
|
+
# + commands_in_path.grep( /^#{Regexp.escape(str)}/ )
|
8
|
+
end
|
9
|
+
|
10
|
+
def commands_in_path
|
11
|
+
commands = []
|
12
|
+
ENV["PATH"].split(':').each do |dir|
|
13
|
+
Dir.glob("#{dir}/*").each do |file|
|
14
|
+
begin
|
15
|
+
stat = File.stat(file)
|
16
|
+
commands << File::basename(file) if stat.executable? and not stat.directory?
|
17
|
+
rescue
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
return commands
|
22
|
+
end
|
data/lib/rubsh.rb
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'commands'
|
3
|
+
require 'rub_readline'
|
4
|
+
require 'prompt'
|
5
|
+
require 'etc'
|
6
|
+
require 'alias'
|
7
|
+
|
8
|
+
def ralias(str)
|
9
|
+
Alias.parse(str)
|
10
|
+
end
|
11
|
+
|
12
|
+
class Rubsh
|
13
|
+
def initialize()
|
14
|
+
Signal.trap('INT') {
|
15
|
+
puts "Enter exit/quit to exit shell"
|
16
|
+
}
|
17
|
+
Signal.trap('SIGKILL') {
|
18
|
+
puts "Enter exit/quit to exit shell"
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.iscmd?(cmd = nil)
|
23
|
+
return nil unless cmd
|
24
|
+
return true if File.exists? cmd
|
25
|
+
ENV["PATH"].split(':').each do |dir|
|
26
|
+
return true if File.exists? "#{dir}/#{cmd.split[0]}"
|
27
|
+
end
|
28
|
+
return false
|
29
|
+
end
|
30
|
+
|
31
|
+
def history
|
32
|
+
history_file = ENV['HOME'] + '/.rubsh/history'
|
33
|
+
return unless File.exists? history_file
|
34
|
+
IO.readlines("#{ENV['HOME']}/.rubsh/history").each do |line|
|
35
|
+
puts line
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def alias(*args)
|
40
|
+
if args.size == 0
|
41
|
+
Alias.show
|
42
|
+
return
|
43
|
+
end
|
44
|
+
first = args.shift
|
45
|
+
Alias[first] = args.join(' ')
|
46
|
+
end
|
47
|
+
def source(fname)
|
48
|
+
load fname
|
49
|
+
end
|
50
|
+
|
51
|
+
def parse_cmd(cmd,follow=true)
|
52
|
+
exit if cmd =~ /exit|quit/
|
53
|
+
exit if cmd == nil
|
54
|
+
call,*args = cmd.split
|
55
|
+
return unless call
|
56
|
+
if Alias[call] and follow #prevent recursion
|
57
|
+
parse_cmd Alias[call] + ' ' + args.join(' '), false
|
58
|
+
elsif Commands.new.respond_to? call
|
59
|
+
begin
|
60
|
+
Commands.new.send call, cmd
|
61
|
+
rescue
|
62
|
+
puts $!
|
63
|
+
end
|
64
|
+
elsif Rubsh::iscmd? call
|
65
|
+
system(cmd)
|
66
|
+
else
|
67
|
+
begin
|
68
|
+
res = eval(cmd,Commands.new.get_binding)
|
69
|
+
p res
|
70
|
+
rescue Exception
|
71
|
+
puts $!
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def parse_cmd2(cmd,follow=true)
|
77
|
+
exit if cmd =~ /exit|quit/
|
78
|
+
exit if cmd == nil
|
79
|
+
call,*args = cmd.split
|
80
|
+
return unless call
|
81
|
+
if Alias[call] and follow #prevent recursion
|
82
|
+
parse_cmd Alias[call] + ' ' + args.join(' '), false
|
83
|
+
elsif ::Rubsh::iscmd? call
|
84
|
+
system(cmd)
|
85
|
+
else
|
86
|
+
begin
|
87
|
+
p eval(cmd, Commands.new.get_binding)
|
88
|
+
rescue Exception
|
89
|
+
puts $!
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def log_cmd(cmd)
|
95
|
+
@fh = File.open(ENV['HOME'] + '/.rubsh/history','a+') unless @fh
|
96
|
+
@fh.puts cmd unless cmd.nil? or cmd =~ /^\s*$/
|
97
|
+
@fh.flush
|
98
|
+
end
|
99
|
+
|
100
|
+
at_exit { @fh.close if @fh }
|
101
|
+
|
102
|
+
def init_readline
|
103
|
+
history_file = ENV['HOME'] + '/.rubsh/history'
|
104
|
+
return unless File.exists? history_file
|
105
|
+
IO.readlines(history_file).each do |line|
|
106
|
+
line.chomp!
|
107
|
+
Readline::HISTORY.push line
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def run
|
112
|
+
ENV['PR1'] ||= '[%h:%w] %u%% '
|
113
|
+
if not File.exists? "#{ENV['HOME']}/.rubsh"
|
114
|
+
FileUtils.mkdir "#{ENV['HOME']}/.rubsh"
|
115
|
+
end
|
116
|
+
if File.exists? "#{ENV['HOME']}/.rubsh/rc.rb"
|
117
|
+
source ENV['HOME'] + '/.rubsh/rc.rb'
|
118
|
+
end
|
119
|
+
init_readline
|
120
|
+
loop do
|
121
|
+
prompt = Prompt::parse ENV['PR1']
|
122
|
+
cmd = Readline::readline(prompt, true)
|
123
|
+
Readline::HISTORY.pop if cmd =~ /^\s*$/
|
124
|
+
log_cmd cmd
|
125
|
+
parse_cmd cmd
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
class String
|
131
|
+
def ls
|
132
|
+
Dir.glob self
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
class Array
|
137
|
+
def du(opt='')
|
138
|
+
switch = ''
|
139
|
+
if (opt.class == Symbol)
|
140
|
+
switch = '-' + opt.to_s
|
141
|
+
else
|
142
|
+
switch = opt
|
143
|
+
end
|
144
|
+
self.each { |f| system("du #{switch} '#{f}'"); }
|
145
|
+
end
|
146
|
+
end
|
data/rubsh.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{rubsh}
|
5
|
+
s.version = "0.0.1"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Daniel Bretoi"]
|
9
|
+
s.date = %q{2009-10-29}
|
10
|
+
s.default_executable = %q{rubsh}
|
11
|
+
s.description = %q{A ruby shell}
|
12
|
+
s.email = %q{daniel@netwalk.org}
|
13
|
+
s.executables = ["rubsh"]
|
14
|
+
s.extra_rdoc_files = ["CHANGELOG", "README.rdoc", "bin/rubsh", "lib/alias.rb", "lib/commands.rb", "lib/prompt.rb", "lib/rub_readline.rb", "lib/rubsh.rb"]
|
15
|
+
s.files = ["CHANGELOG", "Manifest", "README.rdoc", "Rakefile", "bin/rubsh", "lib/alias.rb", "lib/commands.rb", "lib/prompt.rb", "lib/rub_readline.rb", "lib/rubsh.rb", "rubsh.gemspec"]
|
16
|
+
s.homepage = %q{http://github.com/danielb2/rubsh}
|
17
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Rubsh", "--main", "README.rdoc"]
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
s.rubyforge_project = %q{rubsh}
|
20
|
+
s.rubygems_version = %q{1.3.5}
|
21
|
+
s.summary = %q{A ruby shell}
|
22
|
+
|
23
|
+
if s.respond_to? :specification_version then
|
24
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
25
|
+
s.specification_version = 3
|
26
|
+
|
27
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
28
|
+
else
|
29
|
+
end
|
30
|
+
else
|
31
|
+
end
|
32
|
+
end
|
metadata
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rubsh
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Daniel Bretoi
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-10-29 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: A ruby shell
|
17
|
+
email: daniel@netwalk.org
|
18
|
+
executables:
|
19
|
+
- rubsh
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- CHANGELOG
|
24
|
+
- README.rdoc
|
25
|
+
- bin/rubsh
|
26
|
+
- lib/alias.rb
|
27
|
+
- lib/commands.rb
|
28
|
+
- lib/prompt.rb
|
29
|
+
- lib/rub_readline.rb
|
30
|
+
- lib/rubsh.rb
|
31
|
+
files:
|
32
|
+
- CHANGELOG
|
33
|
+
- Manifest
|
34
|
+
- README.rdoc
|
35
|
+
- Rakefile
|
36
|
+
- bin/rubsh
|
37
|
+
- lib/alias.rb
|
38
|
+
- lib/commands.rb
|
39
|
+
- lib/prompt.rb
|
40
|
+
- lib/rub_readline.rb
|
41
|
+
- lib/rubsh.rb
|
42
|
+
- rubsh.gemspec
|
43
|
+
has_rdoc: true
|
44
|
+
homepage: http://github.com/danielb2/rubsh
|
45
|
+
licenses: []
|
46
|
+
|
47
|
+
post_install_message:
|
48
|
+
rdoc_options:
|
49
|
+
- --line-numbers
|
50
|
+
- --inline-source
|
51
|
+
- --title
|
52
|
+
- Rubsh
|
53
|
+
- --main
|
54
|
+
- README.rdoc
|
55
|
+
require_paths:
|
56
|
+
- lib
|
57
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: "0"
|
62
|
+
version:
|
63
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: "1.2"
|
68
|
+
version:
|
69
|
+
requirements: []
|
70
|
+
|
71
|
+
rubyforge_project: rubsh
|
72
|
+
rubygems_version: 1.3.5
|
73
|
+
signing_key:
|
74
|
+
specification_version: 3
|
75
|
+
summary: A ruby shell
|
76
|
+
test_files: []
|
77
|
+
|