Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

In my .bashrc:

function rnew { $HOME/.dotfiles/railsnewapp.sh $1; }

Essentially, I call rnew from any directory, and it creates a directory in ~/code/appname, installs Rails into it, and then I want the pwd to become ~/code/appname.

In ~/.dotfiles/railsnewapp.sh:

#! /bin/bash
appname=$1
appdirectory="$HOME/code/$appname"
if [ -d $appdirectory ]; then
  echo $appdirectory already exists. Not creating Rails app $appname.
else
  mkdir $appdirectory
  cd $appdirectory
  if [ `pwd` == $appdirectory ]; then
    echo "rvm use 1.8.7@$appname" >> "$appdirectory/.rvmrc"
    rvm gemset create $appname
    cd ..
    rails new $appname -m $HOME/code/config/base_template.rb -T -J
    cd $appdirectory
    if [ `pwd` == $appdirectory ]; then
      git init .
    else
      echo Could not create git repo in $appdirectory. Could not switch to that directory.
    fi

  else
    echo Could not switch to directory $appdirectory. No creating Rails app $appname.
  fi
fi

######## how to switch to $appdirectory here so that 
######## when the `rnew` function completes and I'm back at the
######## terminal and the `pwd` is $appdirectory?

Ps. I do not want to do a cd in rnew. As you can see in the script, I am making sure that the app is created in the correct directory and other checks related to directory, so I don't think I can call the script from rnew for a directory that is yet to be created?

share|improve this question

3 Answers 3

up vote 1 down vote accepted

You need to make sure that the directory change happens in the current shell by sourcing it (notice the . before $HOME):

function rnew { . $HOME/.dotfiles/railsnewapp.sh $1; }

It's a shell built-in, from help .:

.: . filename [arguments]
    Execute commands from a file in the current shell.

    Read and execute commands from FILENAME in the current shell.  The
    entries in $PATH are used to find the directory containing FILENAME.
    If any ARGUMENTS are supplied, they become the positional parameters
    when FILENAME is executed.

    Exit Status:
    Returns the status of the last command executed in FILENAME; fails if
    FILENAME cannot be read.

Note that this makes the railsnewapp.sh script be executed in the current shell, variables defined in the shellscript will be available to the shell when it's finished.

share|improve this answer
    
I've updated my question with the complete script. How can I launch it by sourcing when the directory does not yet exist? –  Zabba Apr 29 '11 at 17:51
    
@Zabba: That's a problem in the script, not sourcing. Sourcing means that the script would be executed as if you entered it in your shell directly. I'm not sure what you're trying to achieve, but if you want to cd into the directory if it already exist, just add a cd "$appdirectory" after echo $appdirectory already exists. Not creating Rails app $appname.. –  Lekensteyn Apr 29 '11 at 17:56
    
The script works as expected, it just doesn't switch to $appdirectory upon exit. I already did a cd $appdirectory (just after the rails new...) but it doesn't switch to that directory.. –  Zabba Apr 29 '11 at 17:59
    
@Zabba: any errors? It works for me. –  Lekensteyn Apr 29 '11 at 18:04
    
No errors, it just doesn't work (w/o the .). But I see now that adding the leading . is working, thanks. Now to go read some docs to figure out why exactly! –  Zabba Apr 29 '11 at 18:05

Another option: have your script print the directory name at the end of the script.

...
echo "$appdirectory"
exit

For any error conditions, print the error message to stderr (echo something >&2) and exit with a non-zero return code (exit 1). This is good practice anyway.

Then the function can look like:

rnew () { 
    local dir=$( $HOME/.dotfiles/railsnewapp.sh "$1" )
    [[ $? -eq 0 ]] && cd "$dir" 
}
share|improve this answer

Why not just do it all in that function? Something like:

rnew() {
    local appdir="$HOME/code/$1"
    mkdir "$appdir" || return
    echo "rvm use 1.8.7@$1" > "$appdir/.rvmrc"
    (cd "$appdir" && rvm gemset create "$1") || return
    rails new "$1" -m "$HOME/code/config/base_template.rb" -T -J || return
    cd "$appdir" && git init .
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.