rubsh 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|