Showing posts with label bash. Show all posts
Showing posts with label bash. Show all posts

Monday, December 28, 2015

Bash yourself in the background!

There are many occasions for wanting to run bash scripts in the background. The two that jump out at me are startup scripts and scripts to be run while SSH-ed into a remote server. This post deals mainly with the latter, though it should work for both.

First, create a bash script you want to run. I wanted to monitor the memory of a running EC2 server instance to ensure we didn’t have memory leaking from our app, so here’s my bash script:

# log/memory_profiler.sh
while true
 do
    date 2>&1 | tee -a /srv/application/my_application/log/memory
    free -m 2>&1 | tee -a /srv/application/my_application/log/memory
     sleep 1
 done

This writes the current datetime and the current memory profile to a log file in my app’s directory.

Then, I wanted to run this script from a detached shell session so that when I closed my SSH connection, it would continue running, and also so that I could continue working within the open shell session. To do this, I use a tool called “screen.” Here’s my command:

screen -d -m -S "Memory Profiler" bash log/memory_profiler.sh

Here’s what’s happening: We run the bash script in a detached (-d) shell session, named (-S) “Memory Profiler”. The -m flag ensures a new shell session is created, regardless of where the screen command is called.

Simple enough, right? Then, to view what’s going on with this detached screen session, you just have to reattach the shell session. If you only have one screen running, enter

screen -r

If multiple, you’ll have to specify the named session.

screen -r "Memory Profiler"

Exit as normal using ctrl+c or typing exit.

If you want to get really fancy, you can run this on a schedule - something I've written about previously.

(Lots of good info in the screen docs.)

Monday, November 30, 2015

Bash yourself on a schedule!

To run terminal tasks on a schedule, you have to use something called the “crontab.” It is a file that you edit to include the bash code to run and the times and days to run it.

There are some interesting rules/best practices around editing the crontab.

To start, you have to create a crontab by entering crontab -e. Open and edit it in your favorite editor and save.

If you already have a crontab file that you want to edit, you actually shouldn’t. Rather, get a “copy” of your crontab file by doing crontab -l > new_crontab_copy. Then open the new_crontab_copy in your editor, edit and save.

For either of the above options, “install” your crontab file by giving it to crontab:
crontab my-crontab

(This post won’t be giving any advice on actually writing cron jobs - for that you can check out this Crontab quick reference.)

Friday, March 20, 2015

Bash yourself multiple times

Here's a quick Bash trick. Run command line commands multiple times:

  for i in `seq #{run_how_many_times}`; do #{command_to_run}; done

Example:

  for i in `seq 10`; do rspec spec; done

This is super helpful in debugging tests with intermittent failures.

Wednesday, January 28, 2015

How to make a ruby executable file

Thanks to Commander Coriander for this next bit. I have "borrowed" heavily from the guide there.

How to make a ruby executable file, a fairly major step in gem creation

First, create a Ruby script that will display something. Doesn't matter what, we just need to be able to test that the final executable is working. Let's call our program "awesome_sauce.rb"

Next, instead of having to type ruby awesome_sauce.rb to run our script, let's get it so we can just type awesome_sauce.rb and it infers that we want to use Ruby to run it. To do that, we just need to add the following to the very top of our script:

  #!/usr/bin/env ruby

This is called a "Bash directive" and it tells Bash what program to run our file with by asking for the current configured version of Ruby as specified by the env command. Check out man env for more info on how env works, but essentially, it will use whatever version of Ruby that's configured in your shell session. To find out which Ruby version that is, just run ruby -v

Now we need to make our script executable, so we have to give the file an execute permission. Wikipedia is great for reading all about file permissions for the uninitiated (http://en.wikipedia.org/wiki/File_permissions#Traditional_Unix_permissions). Doing that is just a simple Bash command. Assuming you're already in the same directory as your Ruby script, run this command to add execute permissions:

  chmod 755 awesome_sauce.rb

We're going to add execute permissions which will appear as an x in that line. If you check the file permissions by running ls -l awesome_sauce.rb, the output should be something like this:

  -rwxr-xr-x  1 username  staff     28 Jan  14:02 awesome_sauce.rb

The 'x' as the fourth character tells us that the file can be run directly without calling Ruby first. The following command should get our script to run:

  ./awesome_sauce.rb

It's now an executable! All that's left is cleanup, i.e. removing the prefix ./ and the suffix .rb. The suffix part is easy - just rename your file to awesome_sauce. I still do file renaming with the GUI, but here's how you can do it command-line-ninja style:

  mv awesome_sauce.rb awesome_sauce

Finally, to remove that prefix ./. The reason that is there is because every time we call a Bash program, Bash searches through a predefined list of folders looking for those programs, called the path. Your path is stored as an environment variable on your computer, and can be seen by running:

  echo $PATH

The output should be a long string of various system-critical folders, separated by colons. The one we're looking for is /usr/local/bin/, which is where any user additions should go. If that folder doesn't exist, create it:

  mkdir -p /usr/local/bin/

Now, rather than actually moving our program, let's instead create a symlink (also known as softlink or alias) within the /usr/local/bin/ folder. (To read more about symlinks, short for Symbolic link, Wikipedia is your friend.) To create a symlink, make sure you're still in the same directory as your awesome_sauce and use the ln command:

  ln -s $PWD/awesome_sauce /usr/local/bin/

The $PWD variable will expand to an absolute path to our delicious awesome_sauce.

And you're done! You've now got a fully executable awesome_sauce Ruby script. Pretty slick, friendo.