bash function: md.view
One of my favorite bash functions is md.view, which is available in my dotfiles repository.
# test markdown files, probably a better way to test for programs.
function md.view {
local i=true
type -p markdown &> /dev/null || i=false
if $i ; then
local output="/tmp/md.view-$(date +%F).html";
markdown $1 > "$output";
google-chrome "$output"; # xdg-open would open default browser after next line executes
rm "$output";
else
echo "markdown is not installed"
fi
}
There's not really anything particularly cool about this function. It checks for markdown and reminds me to install it if I haven't yet. It doesn't do this for Google Chrome because that's the first application I install on new machines. Usually, you'd use xdg-open to choose a browser, but this can cause problems with the remove command at the end of the function (depending on how the browser creates its process).
Anyway, this is really useful when I'm creating README files using markdown for my github repositories. For instance, I was just updating a README to refer to *_32.png images. The problem is that * and _ are special tokens in markdown. I'd never attempted to escape one after the other, which is often broken in parsers. With this function in my extended .bash\functions, I can quickly check output with:
$ md.view README.md
I know, it's such a simple thing to have as a favorite. Sometimes really simple things have a huge impact, especially if you type out README files regularly
dotfiles backup using GitHub
I was recently looking for a solution to backup my configuration files (bash, vim, etc) using GitHub. After some looking around, I've compiled a pretty nice project for myself.
First, this script checks dependencies. My dependencies are git, ruby, vim, tree, rake, gem, bundle, and trash. You could check out the code and add any number of dependencies here. Rubygems and bundler are required because the script later installs all gems listed in Gemfile.
Next, the script copies ~/.bashrc to ~/.bashrc.local. This allows you to keep your current bash configuration as a 'local-only' config that doesn't get copied or committed to github.
The script, as I copied most of bootstrap.sh and the rakefile from @gf3, expects the repository to be cloned to ~/.dotfiles. From there, it calls rake.
Rake looks at every file in ~/.dotfiles and copies the corresponding file relatively from ~/ to, essentially, ~/dotfiles-backup/`date`. I recommend first running the backup to make sure your files are properly backed up.
rake backup
The script then calls 'bundle install' to install all gems. It then copies all files from ~/.dotfiles to replace those relative files that were previously backed up from ~/.
The post-install displays a message to remind you to edit .gitconfig and .hgrc.
Because I've done some copying and compiling, these are relative close to the three projects in the README for right now.
Here is an excerpt from the README:
Bash
$ tree ~/.bash
/home/jim/.bash
├── aliases
├── completions
├── completion_scripts
│ └── git_completion
├── config
├── functions
├── paths
└── prompt
The above files are loaded by .bashrc. The files are pretty self-explanatory, other than prompt which colorizes the bash prompt with tweaks for git.
Cool Aliases
- cd : pushd
- bd : popd
- cd.. | .. : back one directory
- cd... | ... : back two directories
- ^ up to five directories
- rm : trash
- undopush
- ip
- GET | HEAD | POST | PUT | DELETE | TRACE | OPTIONS
Config
- sets editor to vim
- sets English/UTF-8
- sets manpager
- sets commands to ignore in history
- sets noclobber (e.g. prevents
cat > IMPORTANT_FILEmistakes ) - sets nocaseglob (e.g.
ls ~/.B*will list contents of~/.bash)
Functions
The two functions, md and c may not seem like much, but they simplify some commands. For example:
$ md projects; git clone git@github.com:jimschubert/dotfiles.git && cd dotfiles
In the above line, md will create the projects directory and cd into it.
c stands for 'code' and works like this:
jim at computer in ~
$ pwd
/home/jim
jim at computer in ~
$ c dotfiles
~/projects/dotfiles ~
jim at computer in ~/projects/dotfiles on master
$
You can change it to whatever shortcut and issue reload, which is also an alias from this setup.
Screenshot
Notice the color scheme and github branch notifications created by ~/.bash/prompt.
Posting complex models to ASP.NET MVC
Nick Riggs wrote a nice little jQuery plugin called postify that I have found extremely handy on many occasions. The code builds posted data into a format which is more understandable to the default ModelBinder in ASP.NET MVC.
Check out his post for details.
Here is Nick Riggs code for $.postify:
// postify.js
// Converts an object to an ASP.NET MVC model-binding-friendly format
// Author: Nick Riggs
// http://www.nickriggs.com
$.postify = function(value) {
var result = {};
var buildResult = function(object, prefix) {
for (var key in object) {
var postKey = isFinite(key)
? (prefix != "" ? prefix : "") + "[" + key + "]"
: (prefix != "" ? prefix + "." : "") + key;
switch (typeof (object[key])) {
case "number": case "string": case "boolean":
result[postKey] = object[key];
break;
case "object":
if (object[key].toUTCString)
result[postKey] = object[key].toUTCString().replace("UTC", "GMT");
else {
buildResult(object[key], postKey != "" ? postKey : key);
}
}
}
};
buildResult(value, "");
return result;
};
Running additional Google Chrome profiles in Linux
Google Chrome supports running multiple profiles.
In newer versions of Google Chrome, you'll be able to enable profiles by navigating to chrome://flags and enabling Multiple Profiles. Restart the browser, and you'll have a switcher and multiple profiles which can be activated in different windows. This allows you to sync to different gmail accounts. For instance, if you have a personal account and a work or school account, each with different bookmarks... you can run two or three different profiles and have access to all of your data.
If you're using an older version of Chrome or Chromium and you don't have the Multiple Profiles option, you can use the switch
--user-data-dir
when opening the browser and the profile for your session will be pulled from the given folder instead of the Default folder. The folder specified should be created automatically. To be safe, I like to create the folder before providing it as an argument.
As explained here, the default directory is located at:
Google Chrome: ~/.config/google-chrome/Default Chromium: ~/.config/chromium/Default
Open a terminal and create a new directory for your second profile. For instance:
mkdir ~/.config/google-chrome/work
Then, open Google Chrome with the switch:
google-chrome --user-data-dir='~/.config/google-chrome/work' &
If this is a profile you'll be using often, you can also create a menu entry under Applications -> Internet ('Chrome|Work', maybe?).
System.Data.OracleClient and Windows 7… love at first sight!
</sarcasm>
I spent nearly two days trying to resolve this issue. My new desktop at work is running Windows 7 (64-bit) and some of our applications are still using System.Data.OracleClient as an adapter instead of Oracle's own ODP.NET. Microsoft's driver interops with Oracle's own client installed on the developer machine (oci.dll). We need to continue running our web applications under 32-bit IIS, which is where the problem lies.
FYI... According to Microsoft:
The types in System.Data.OracleClient are deprecated. The types are supported in version 4 of the .NET Framework but will be removed in a future release. Microsoft recommends that you use a third-party Oracle provider.
Back to the comment about IIS. Apparently, IIS 7 in Windows 7 is 64-bit only. Yes, you can set an application pool to 32-bit. That would be perfectly fine, except that Oracle's client native methods don't like running through WoW64. So, you have to install both the 64-bit client and the 32-bit client. After all, 32-bit adapter code can't call a 64-bit client. If you fire up procmon, though, you'll see that calling the 32-bit Oracle client still queries 64-bit settings (and fails if they don't exist). WoW64!, indeed.
Continue reading to see my resolution...
Note: this forces Oracle 11.2.0.1 to use 32-bit only in a 64-bit environment.
Linux tip: Alias ‘cd’ in bash shell
A while ago, I stumbled across an excellent article at O'Reilly with tips for your bash shell.
I wanted to expand on the "pushd/popd" section a little.
First, check your ~/.bashrc file for the following lines:
if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases
fi
This checks that the ~/.bash_aliases file exists, and if it does, it loads it using the '.' builtin. If you aren't familiar with the source/. builtin, here is an excerpt from the documentation:
. (a period)
. filename [arguments]Read and execute commands from the filename argument in the current shell context. If filename does not contain a slash, the PATH variable is used to find filename. When Bash is not in posix mode, the current directory is searched if filename is not found in $PATH. If any arguments are supplied, they become the positional parameters when filename is executed. Otherwise the positional parameters are unchanged. The return status is the exit status of the last command executed, or zero if no commands are executed. If filename is not found, or cannot be read, the return status is non-zero. This builtin is equivalent to source.
Now, create or edit ~/.bash_aliases with the following content:
alias cd="pushd" alias bd="popd" alias cd..="cd .." alias cd...="cd ../.." alias cd....="cd ../.." alias cd.....="cd ../../.." alias cd......="cd ../../../.."
This aliases cd to push the result onto the directory stack (pushd). Then, we introduce a bd command to pop the last directory off the stack (popd).
If you're like me, you get tired of typing cd ../../../.., which is still faster than typing cd /home/jim/projects/al [TAB]/src or something similar. So, the last lines alias quite a few levels of directory changes so you type cd.. followed by the number of directories you want to navigate back.
Here are some examples:
jim@schubert:~$ cd projects/newtabredirect/ ~/projects/newtabredirect ~ jim@schubert:~/projects/newtabredirect$ cd ~/projects/select-actions/ ~/projects/select-actions ~/projects/newtabredirect ~ jim@schubert:~/projects/select-actions$ cd ~/Documents/blogs/ ~/Documents/blogs ~/projects/select-actions ~/projects/newtabredirect ~ jim@schubert:~/Documents/blogs$ bd ~/projects/select-actions ~/projects/newtabredirect ~ jim@schubert:~/projects/select-actions$ cd.... ~ ~/projects/select-actions ~/projects/newtabredirect ~ jim@schubert:~$ pwd /home/jim
Linking to a Google Doc .doc as .pdf
I recently decided to update my resume, which forced me to revisit an issue I originally faced when posting my resume to my site: I am writing it as a doc file in Google Docs but I want to link to it as a PDF and have my updates visible immediately.
I know this is a selfish thing to want, and I settled for the quick and easy solution of copying the PDF to my host and pointing to the local file. After updating my resume today, I thought, "I'm sure someone has already encountered this." A quick search on Google took me to a Google knol article in which the other provides a link which will convert the Google Doc (provided by a document id) to a desired format. This link causes the PDF to download immediately, but when passed to the document viewer, it works as expected. Perfect!
Here is the article citation:
Google Docs Guide 2. Google Docs Help: Howto Link Straight To A Public Docs Pdf Or Other Supported File [Internet]. Version 2. Knol. 2008 Oct 8. Available from: http://knol.google.com/k/google-docs-guide-2/google-docs-help-howto-link-straight-to/2vcnhxffa8r42/20.
And the link template described in the article:
http://docs.google.com/MiscCommands?command=saveasdoc&exportformat=[FORMAT]&docID=[ID]
Check out my resume for an example.
Syncing between Motorola Droid and Banshee or Rhythmbox in Ubuntu
I like to download those cheap albums on AmazonMP3 that are like "The 99 Darkest Classical Pieces" or whatever. The AmazonMP3 download, however, puts these mp3s in folders according to the artist instead of Various Artists or by album name. Because the Droid's music player reads music based on the folder structure and not on the id3 tags, this means I have about 30 or 40 different entries for the same album. It's annoying, to say the least.
I recently decided to use Rhythmbox to pull all of the music from the Droid and then copy it back over to see if it would automatically put the mp3s in the correct folders. To my surprise,
Tip for Writers and Novelists: Use Subversion to track changes in your work!
As a developer, I take some things like version control for granted.
Recently, I suggested version control to my wife to make it easier for her to compare her current revisions with earlier revisions. Currently, when she wants to make a new revision, she creates a new file with a different filename. This doesn't give her to Word comparing or change tracking. So, if she deleted a paragraph two, three, or twenty revisions ago, she could easily go back to a draft containing the paragraph and retrieve the text or compare against the current revision. It would even be possible to check out the earlier revision!
On top of change tracking, a subversion repository offers a complete backup of documents. This would be excellent for someone who is worried about losing their documents. For instance, you can create a subversion repository on an external hard drive and you'll never lose anything earlier than your last check-in. Granted, you have to adopt the version control process, but the benefits greatly outweigh the possible headaches of having no sort of version control or revision history.
For any writers who may stumble across my site, this post will walk you through setting up a local subversion repository for free.
Required Download: TortoiseSVN
My version of TortoiseSVN is 1.6.6. Although your version may be slightly different than the screenshots, the overall steps should remain the same. After installing TortoiseSVN, be sure to reboot your computer to make sure the svn caching mechanism is working. Then, continue reading...
System76 Ubuntu NetBook and Tethering on Verizon Droid (Android)
One of the first things I wanted to do when I got my netbook was to setup tethering. However, I don't want to pay $30 more a month just to view the same pages I'd otherwise be viewing on my phone (i.e. Facebook, Twitter, Google News/Gmail). The answer to this is an application called EasyTether. It's currently only $10 on the Android Market. Click here to download EasyTether.
The setup guide in EasyTether will walk you through getting the application configured on your phone and connecting that to your computer. However, some people may have Linux-based NetBooks and not have the technical knowledge to write a simple script to startup 'easytether' in a console. I'd like to provide those steps. Please read on if you're interested!
Note: You *MUST* have your sudo password to proceed.

