如何在 Bash 脚本末尾更改目录?

如何在 Bash 脚本末尾更改目录?

在我的.bashrc

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

本质上,我rnew从任何目录调用,它会在中创建一个目录~/code/appname,将Rails安装到其中,然后我希望pwd变成~/code/appname

~/.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?

诗篇我不想cd在 中执行rnew。正如您在脚本中看到的,我正在确保应用程序在正确的目录中创建,并进行与目录相关的其他检查,所以我不认为我可以rnew为尚未创建的目录调用脚本?

答案1

另一种选择:让脚本在脚本末尾打印目录名称。

...
echo "$appdirectory"
exit

对于任何错误情况,将错误消息打印到 stderr ( echo something >&2) 并以非零返回代码退出 ( exit 1)。无论如何,这都是很好的做法。

那么该函数看起来如下:

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

答案2

您需要通过获取目录更改来确保目录更改发生在当前 shell 中(请注意之前.$HOME):

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

它是一个内置的 shell,来自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.

请注意,这会使 railsnewapp.sh 脚本在当前 shell 中执行,完成后,shellscript 中定义的变量将可供 shell 使用。

答案3

为什么不直接在这个函数中完成所有操作呢?例如:

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 .
}

相关内容