Find DrewDahl on Facebook! Find DrewDahl on Twitter! View Andrew Dahl's Profile Drew's Blog

Programming

Using Ruby to run commands on a lab of Linux machines

by Drew Dahl on Feb.24, 2011, under Linux, Programming

Lately, I’ve been getting acquainted with Rails development at work. It’s been a pretty steep learning curve (for that matter, I guess it still is), but I’ve enjoyed it thus far. So, with my new found Ruby skills (or, I guess more-so my new found need to learn Ruby), I wrote a script that uses SSH to iteratively connect to every computer in a lab and update them. This could be used for just about anything, but for my instance it was updating a lab. There was a bit more to my script as I needed to recompile some device drivers when there was a new kernel, but for simplicities sake, I’ve ripped them out. Hope this helps someone else!

First, you’ll need to install the ruby-ssh library.

sudo gem install net-ssh
sudo gem install highline

And, the script is:

#!/usr/bin/ruby

require 'rubygems'
require 'net/ssh'
require 'highline/import'

hosts=[ "host1",
            "host2" ]

cmds = ["yum -y update",
             "init 6"]

username = "root"

# Assuming that all hosts have the same password
password = ask("Enter Password: ") { |q| q.echo = false }

hosts.each do |host|
    Net::SSH.start( host , username, :password => password) do |ssh|
        puts "Connected to #{host}"
        cmds.each do |cmd|
            puts "Performing #{cmd} on #{host}"
            output = ssh.exec! cmd do |ch, stream, data|
                if stream == :stderr
                    puts "Error: #{data}"
                else
                    puts data
                end
            end
        end
    end
end

And, that’s all there is to it! There’s a real lack of comments, but I feel it’s pretty self-explanatory. Enjoy!

2 Comments :, , , , , more...

Simple Shell in C

by Drew Dahl on Dec.02, 2010, under Linux, Programming

Well, life has been a 24/7 hell for the last few months. As an example of how much free time I’ve had, I haven’t seen a couple of my really good friends since July or August. Hopefully they haven’t forgotten about me ;-)

In any case, I wrote a pretty good simple shell in C for my Operating Systems class. I finished it back in October, but haven’t posted it until now as several students just recently finished theirs.  Wouldn’t want them to cheat. ;-)

Less rambling.  The reason I’m posting this is that I think it is a really good example of using some basic system calls, such as malloc(), printf(), fgets(), strtok(), strcmp(), strcpy(), sprintf(), free(), chdir(), fork(), execpe(), opendir(), and wait(). Hopefully someone finds this useful :-)

#include <stdio .h>
#include <stdlib .h>
#include <unistd .h>
#include <string .h>
#include <sys /types.h>
#include <dirent .h>

const int SIZE=100;
const int ARGSIZE=10;

void cd(char *dir)
{
    int ret = 0;

    //Check to see if directory argument is blank
    if(dir == '\0')
        dir = getenv("HOME");
    //Check to see if directory argument starts with ~ and replace it with $HOME
    else if(dir[0] == '~')
    {
        char* temp = malloc(SIZE);
        strcpy(temp,dir+1);
        sprintf(dir,"%s%s",getenv("HOME"),temp);
        free(temp);
    }

    //Change Directory
    ret = chdir(dir);
           
    if(ret != 0)
        fprintf(stderr,"Failed to enter directory: %s\n",dir);
    else
        printf("%s\n",dir);
}

void ls(char *dir)
{
    DIR* open_dir;
    struct dirent* drent;

    if(dir == '\0') //See if dir is valid, if not set it to current directory
        dir = (char*)".";

    if((open_dir = opendir(dir)) != NULL) //open dir
    {
        while((drent = readdir(open_dir)) != NULL) //get contents of directory
        {
            printf("%s\n",drent->d_name); //print contents
        }
   
        closedir(open_dir); //close dir
    }
}

void execute(char *args[])
{
    int status;
    pid_t pid;

    //fork and execute the command   
    if((pid = fork()) == 0)
    {
        execvp(args[0],args);
        //execvp should only return if there was an error

        fprintf(stderr,"Unknown command\n");
        exit(0);
    }
    else if(pid < 0)
    {
        fprintf(stderr,"Failed to fork(): %s\n", args[0]);
        status = -1;
    }
    //Wait for child so stdin and stdout aren't fighting for use   
    else
        while(wait(&status) != pid)
           continue;
}

int main(int argc, char *argv[], char *envp[])
{
    char *temp;
    char *line;
    char *args[ARGSIZE];
    char argIndex = 0;

    for(;;)
    {
        line = malloc(SIZE); //Allocate memory for line
        argIndex = 0; //Initialize argIndex

        printf("\n[SHELL ] ");

        fgets(line, SIZE, stdin); //Get Input

        temp = strtok(line, " \n"); //Get input into an array to use w/ execve

        while(temp != NULL)
        {
            args[argIndex] = temp;
            argIndex++;
            temp = strtok(NULL, " \n");
        }

        args[argIndex] = (char*) 0; //Set the end of the arguments list

        if(strcmp(args[0], "quit") == 0 || strcmp(args[0], "exit") == 0)
            break; //break out for for(;;) loop

        if(line== "\n")
            printf("[SHELL ] ");
        else if ((strcmp(args[0], "ls") ==0))
            ls(args[1]); //run ls
        else if ((strcmp(args[0], "cd") == 0))
            cd(args[1]); //run cd
        else
            execute(args); //Fork and Execute command

        free(line); //Free memory from line
    }

    printf("\n");
    return 0;
}

And, in case you want a Makefile (I know I do!):

CC = gcc
OBJECTS =
PROC = shell

CFLAGS =
LFLAGS =

$(PROC):
$(CC) $(CFLAGS) simpleshell.c -o $(PROC) $(LFLAGS)
all:
$(CC) $(CFLAGS) simpleshell.c -o $(PROC) $(LFLAGS)
clean:
rm -rf *.o *.c~ $(PROC)

Enjoy!

(P.S… Todoist-for-Android updates will follow! I promise! The holidays are coming after all! :-] )

2 Comments more...

Make it snow

by Drew Dahl on Jan.17, 2010, under HowTo, Programming

A friend of mine set this up on his page for Christmas. I thought it was kind of cool, so I thought I’d post it here.

You can download the code from my site directly here. (Right click or option-click the link and choose “Save As…” to download this file.)

Leave a Comment : more...

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!