Custom bash auto-completion using Ruby
Using what I showed you in the how to run Ruby code from within a bash script post, I will follow that up with an easy way to create a custom bash auto-completion function.
The Scenario…
I like to keep all my code and projects in my ~/Development directory. I typically create an alias which takes me to this path, and depending what projects I’m working on, I’ll add/remove aliases accordingly to get to the relevant projects quickly. But this is quite manual and cumbersome, and it requires constant maintenance. What I’d like is an auto-complete function that dynamically picks up any new directory I create in the ~/Development directory.
All the functions detailed below should either go into your
.bashrcfile, or a file that is sourced from your.bashrcfile.
Get rid of that alias
The first thing to do is change my alias to a function. So, instead of this…
alias d="cd ~/Development"
…we want this:
function d { cd ~/Development/$1; }
Create the list of choices
Next, we need a function which returns a list of all the directories in the ~/Development directory, which will serve as our auto-completion choices. We can use Ruby here to make things nice and clean…
#!/usr/bin/env sh
/usr/bin/env ruby <<-EORUBY
class ProjectCompletion
def initialize(command)
@command = command
end
def matches
projects.select do |task|
task[0, typed.length] == typed
end
end
def typed
@command[/\s(.+?)$/, 1] || ''
end
def projects
%x[ls ~/Development].split
end
end
puts ProjectCompletion.new(ENV["COMP_LINE"]).matches
EORUBY
Bootstrap it!
Finally, all we need is to tell bash to use this script. We do that with this command (your own paths may vary of course):
complete -C ~/.dotfiles/completion_scripts/project_completion -o default d
Reload your shell and voila! You now have bash auto-completion for all your coding projects. This is very easily customised too, so you can create auto-complete scripts for all kinds of other things, locations, tasks etc.
You can now easily reach your coding projects using auto-complete, without the need for aliases. For example, if you had a directory structure like this…
~/Development ~/Development/project_1 ~/Development/project_2
…you could easily see a list of projects doing this:
d proj<tab>
For more information see my dotfiles project.
Hope this helps.
Setting up Ubuntu 11.10 for Rails development… Just Right!
Further to my previous post on how to setup Ubuntu 11.10 for Rails development, I have now created a bash installer script to automate the whole laborious process for your pleasure… well it’s for my own pleasure really, but I like to share!
There are two installer scripts:
- Ubuntu user will setup your Ubuntu 11.10 environment will all the usual goodies you normally should install after a clean install / upgrade.
- Rails developer will setup your Ruby environment using RVM, along with all the supporting things that you will need to get up and running in no time.
The installers are updated regularly so check the git pages for full details, but some of the key things that are installed are…
The Ubuntu user installer will hook you up with these (among others)…
- Medibuntu repositories
- Ubuntu Restricted Extras
- Configuration Editor (dconf-tools)
- Compiz Config Settings Manager
- Synaptic
- Terminator
- GNOME Tweak Tool
- VLC
- Jupiter
- Caffeine
- Web apps and Sushi file previewer
- Simple LightDM Manager
- Sysmonitor App Indicator
- Dropbox
- OpenJDK (Java 7) – optional
Some of the things the Rails developer installer will setup are…
- SSH key – optional
- Essential Ubuntu libraries
- Ruby 1.8.7 from Ubuntu repostories with additional libraries
- Git and Git Gui
- MySQL 5.1 with admin GUI tools
- MongoDB 2.0.1 – optional
- ack
- ImageMagick
- RVM (Ruby Version Manager) with these rubies: 1.8.7 stable and 1.9.2 stable
Head over to the git repository for instructions on how to run the installers and also for more details about what it actually installs:
https://github.com/edjames/just_right
Simples.
Nice & clean config using dotfiles
Clean up your shell environment by using my dotfiles project.
It’s as easy as running a simple rake task… then you have a clean, customizable shell environment all set up and ready to go!
Please see the git repository for more details on what is does and how to install.
You can find it all here: https://github.com/edjames/dotfiles
As mentioned before, you will have to have Rake installed before you run the automated installer, but it will set things up nicely. Just right in fact.
Hope you like it.
Setting up Ubuntu 11.10 for Rails development
This method is depricated and has been replaced by an automated installer. See this post for more details:
Setting up Ubuntu 11.10 for Rails development… Just Right!
The setup for Ubuntu 11.10 almost identical to the 11.04 setup. A few libraries have changed but otherwise it’s exactly the same.
As before, I like to have a system Ruby installed. This has always been a precautionary measure but has saved me plenty of pain with past installs.
sudo apt-get install build-essential openssl ri ruby ruby1.8 ruby-dev rake libruby1.8 git-gui gitk libxslt1-dev libreadline6 libreadline6-dev curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-0 libsqlite3-dev sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev ncurses-dev automake libtool bison
Then install RVM (see the RVM website for the latest installation instructions).
$ bash < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)
Then run the following command, and… READ THE NOTES!
rvm notes
Make sure you read the RVM post-installation notes. You will get an updated list of OS dependencies and instructions on how to modify your .bash file. If you don’t do this you will probably drive yourself crazy trying to get RVM to work. You will fail.
Finally, install whatever rubies you want:
rvm install 1.8.7 rvm install 1.9.2 rvm install 1.9.3
Finally, install MySQL (and the MySQL GUI tools)…
sudo apt-get install mysql-server libmysqlclient-dev libmysql-ruby mysql-admin
Happy coding!
Run Ruby code from within a shell script
If you need to run Ruby code from within a shell script, you could easily execute a Ruby script with a simple bash command. This means you will have two files – one bash script and one Ruby script.
However, what if you want to combine the two file into a single file?
Simple, using a heredoc in your bash script, we simply pass the entire heredoc to the ruby executable. Create a file called hybrid which contains the following code:
#!/usr/bin/env sh echo "This is bash!" /usr/bin/env ruby <<-EORUBY puts 'This is ruby!' EORUBY
Running the above bash script will produce this:
$ . hybrid This is bash! This is ruby!
Hope this helps.
Find duplicate file names between two folders
Ever need to check whether files in one folder exist in another folder? Here’s a quick bash script to do just that…
for file in * ; do [ -f ../images/$file ] && echo $file ; done
So, assuming you want to check that any files in your current folder already exist in the ../images folder, this bash script will print the names of any duplicate files.
All it’s doing is iterating over the file in your current folder, checking to see if that file exists in the ../images folder, and if ti does, print the file name.
Nice.
Awesome Conky config
With Ubuntu 11.04 and Unity, it’s no longer possible (for now) to use panel indicators for system monitoring. Things like SystemMonitor for example, which were extremely useful, can no longer be placed in the panel.
So, I’ve switched to Conky, which I must say, absolutely rocks!
This is what is looks like on my desktop, with the config too!
background no
font Sans:size=8
#xftfont Sans:size=10
use_xft yes
xftalpha 0.9
update_interval 3.0
total_run_times 0
own_window yes
own_window_type normal
own_window_transparent yes
own_window_hints undecorated,under,sticky,skip_taskbar,skip_pager
double_buffer yes
minimum_size 220 5
maximum_width 220
draw_shades yes
draw_outline no
draw_borders no
draw_graph_borders yes
default_color white
default_shade_color black
default_outline_color green
alignment middle_right
gap_x 12
gap_y 35
no_buffers yes
uppercase no
cpu_avg_samples 2
override_utf8_locale no
uppercase no # set to yes if you want all text to be in uppercase
TEXT
${color white}SYSTEM ${hr 1}${color}
Hostname: $alignr$nodename
Kernel: $alignr$kernel
Uptime: $alignr$uptime
Temp: ${alignr}${hwmon 0 temp 1}C
CPU: ${alignr}${freq} MHz
Processes: ${alignr}$processes ($running_processes running)
Load: ${alignr}$loadavg
CPU1 ${alignr}${cpu cpu1}%
${cpubar cpu1 4}
CPU2 ${alignr}${cpu cpu2}%
${cpubar cpu2 4}
Ram ${alignr}$mem / $memmax ($memperc%)
${membar 4}
Swap ${alignr}$swap / $swapmax ($swapperc%)
${swapbar 4}
Highest CPU $alignr CPU% MEM%
${top name 1}$alignr${top cpu 1}${top mem 1}
${top name 2}$alignr${top cpu 2}${top mem 2}
Highest MEM $alignr CPU% MEM%
${top_mem name 1}$alignr${top_mem cpu 1}${top_mem mem 1}
${top_mem name 2}$alignr${top_mem cpu 2}${top_mem mem 2}
${color white}FILE SYSTEM ${hr 1}${color}
Root: ${alignr}${fs_free /} / ${fs_size /}
${fs_bar 4 /}
Windows: ${alignr}${fs_free /media/windows} / ${fs_size /media/windows}
${fs_bar 4 /media/windows}
${color white}NETWORK ${hr 1}${color}
Down ${downspeed eth0} k/s ${alignr}Down ${downspeed eth1} k/s
Up ${upspeed eth0} k/s ${alignr}Up ${upspeed eth1} k/s
Setting up Ubuntu 10.10 for Rails development
The setup for Ubuntu 10.10 is a little different to the 10.04 setup. I seem to have to manually install quite a few more packages to get things moving. But as usual it’s easy enough once you’ve done it once…or a few times.
First, install the necessary packages and a system Ruby (1.8.7). RVM will ignore the system installed Ruby, but in my experience you will save yourself a lot of hassle by having a system-installed Ruby.
sudo apt-get install ri ruby ruby1.8 ruby-dev rake libruby1.8 zlib1g-dev libssl-dev libreadline5-dev libncurses5-dev build-essential curl git-core git-gui gitk libxml2 libxml2-dev libxslt1-dev bison autoconf
Then install RVM (see the RVM website for the latest installation instructions).
bash < <(curl -B http://rvm.beginrescueend.com/install/rvm)
Then run the following command, and… READ THE NOTES!
rvm notes
Make sure you read the RVM post-installation notes. You will get an updated list of OS dependencies and instructions on how to modify your .bash file. If you don’t do this you will probably drive yourself crazy trying to get RVM to work. You will fail.
Finally, install whatever rubies you want:
rvm install 1.8.7-head rvm install 1.9.2-head
Then install MySQL (and the MySQL GUI tools)…
sudo apt-get install mysql-server libmysqlclient-dev libmysql-ruby mysql-admin
Happy coding!
Easy Remote Desktop connections in Ubuntu
SSH is easy, right? Thought so. However, establishing a remote desktop connection with an Ubuntu (or Linux!) machine is a little more tricky.
If you’re ever tried setting up VNC you’ll know how horrible it is to get going. You have to do all kinds of silly things with config files, not to mention making sure that the VNC server is running on the remote machine in order to accept in-coming connection requests to begin with. Awful.
So, instead of inflicting that kind of pain on yourself, just install the xrdp package…
sudo apt-get install xrdp
Then open your favourite Remote Desktop client and you should be able to connect immediately. As I’m connecting from my Ubuntu laptop, I just setup a Terminal Services connection.
It works beautifully.
Setting up Ubuntu 10.04 for Rails development
Every time a new version of Ubuntu is released use it as an opportunity to rebuild my development environment. It keeps things clean and fresh, and because I develop exclusively in virtual machines it’s easy and fast to do if you don’t have to do too much searching around.
Here’s what I want in my development environment on Ubuntu:
- RVM
- Apache and Passenger
- MySql and SQLite
- RubyMine development IDE
- Optional: Install UnixODBC and FreeTDS for SqlServer connectivity
Fairly standard setup, so let’s get started…
RVM
Before I install RVM, I always install Ruby 1.8.7. I’ve run into strange problems when I’ve installed RVM without first installing Ruby. I also like having a system Ruby installed. Typically this will be 1.8.7 simply because this is the version of Ruby that’s in the Ubuntu repositories.
sudo apt-get install irb libopenssl-ruby libreadline-ruby rdoc ri ruby ruby1.8 ruby-dev rake libopenssl-ruby git-core gitk git-gui libxml2 libxml2-dev libxslt1-dev libncurses5-dev libreadline5-dev
Then install RVM (see the RVM website for the latest instructions).
If RVM doesn’t already have Rubygems installed, here’s the manual recipe::
cd /usr/local/src sudo wget http://production.cf.rubygems.org/rubygems/rubygems-1.4.1.tgz sudo tar xzvf rubygems-1.4.1.tgz cd rubygems-1.4.1 sudo ruby setup.rb sudo update-alternatives --install /usr/bin/gem gem /usr/bin/gem1.8 1 sudo gem update --system
Before we move on, a couple of quick tweaks to two files in your home folder. First, add the following to the .gemrc file:
--- :backtrace: false :benchmark: false :bulk_threshold: 1000 :sources: - http://rubygems.org/ - http://gems.github.com :update_sources: true :verbose: true gem: --no-ri --no-rdoc
Then add this to the .gitconfig file:
[user]
name = [your name]
email = [your email]
[color]
ui = auto
Apache and Passenger
A basic installation of Apache and Passenger is easy:
sudo aptitude update sudo aptitude install apache2 sudo gem install passenger sudo passenger-install-apache2-module
The final command will check your system for dependencies. In my case the following command will sort that out:
sudo apt-get install build-essential sudo apt-get install libcurl4-openssl-dev libssl-dev zlib1g-dev apache2-prefork-dev libapr1-dev libaprutil1-dev
Rerun the passenger install command and it should succeed after all dependencies have been satisfied.
MySQL and SQLite
MySQL is essential, but I usually install SQLite too, because it’s simple and comes in handy sometimes.
sudo apt-get install libsqlite3-dev sqlite3 sqlite3-doc sudo gem install sqlite3-ruby sudo apt-get install libmysqlclient-dev mysql-server emma sudo gem install mysql
RubyMine development IDE
For RubyMine to run we need to install a java runtime. I’ve found the Sun JRE to be best, and this is how we get it:
sudo add-apt-repository "deb http://archive.canonical.com/ lucid partner" sudo apt-get update sudo apt-get install sun-java6-jre sun-java6-plugin sun-java6-fonts
Once that’s done, do a quick test to make sure everything is ok…
java -version
Now download and extract the RubyMine package and create a menu link to start RubyMine. You will need your license key when it starts.
Optional: Install UnixODBC and FreeTDS for SqlServer connectivity
This is optional because unless you need to connect to Microsoft SqlServer (I do for work!) you won’t need to do this. I’ve split these into separate commands because the sequence is very important – RUN EACH COMMAND SEPARATELY!
sudo apt-get install unixodbc sudo apt-get install unixodbc-dev sudo apt-get install freetds-dev sudo apt-get install freetds-bin sudo apt-get install tdsodbc sudo apt-get install libiodbc2
Install the Ruby ODBC binaries (we’ve found that this specific version works best for us):
cd /usr/local/src sudo wget http://www.ch-werner.de/rubyodbc/ruby-odbc-0.9997.tar.gz sudo tar zvxf ruby-odbc-0.9997.tar.gz cd ruby-odbc-0.9997 sudo ruby extconf.rb --disable_dlopen make make install
Test the connection in irb:
require 'rubygems'
require 'dbi'
dbh = DBI.connect('dbi:ODBC:[dsn_name]', [username], [password])
You will need to manually configure the FreeTDS config files to get this working, but this is easily found on the web.

