2

我有一个 bash 脚本,用于从我目前所在的任何地方从源目录移动到 bin 目录(我称这个脚本为“teleport”)。因为它基本上只是一个美化的“cd”命令,所以我必须在当前的 shell 中运行它(即 . ./teleport.sh )。我在我的 .bashrc 文件中设置了一个别名,以便 'teleport' 匹配 '. 传送.sh'。

我第一次运行它,它工作正常。但是,如果我在它运行一次后再次运行它,它不会做任何事情。如果我关闭我的终端然后打开一个新终端,它会再次工作,但只是第一次。我的直觉是 BASH 内部发生了一些我不熟悉的事情,所以我想我会通过这里的专家来运行它,看看我是否能得到答案。

脚本是:

numargs=$#

function printUsage 
{
        echo -e "Usage: $0 [-o | -s] <PROJECT>\n"
        echo -e "\tMagically teleports you into the main source directory of a project.\n"
        echo -e "\t PROJECT: The current project you wish to teleport into."
        echo -e "\t -o: Teleport into the objdir.\n"
        echo -e "\t -s: Teleport into the source dir.\n"
}

if [ $numargs -lt 2 ]
then
        printUsage
fi

function teleportToObj
{
  OBJDIR=${HOME}/Source/${PROJECT}/obj
  cd ${OBJDIR}
}

function teleportToSrc
{
  cd ${HOME}/Source/${PROJECT}/src
}

while getopts "o:s:" opt
do
  case $opt in
    o)
      PROJECT=$OPTARG
      teleportToObj
      ;;
    s)
      PROJECT=$OPTARG
      teleportToSrc
      ;;
   esac
done

我的用法是这样的:

sjohnson@corellia:~$ cd /usr/local/src
sjohnson@corellia:/usr/local/src$ . ./teleport -s some-proj
sjohnson@corellia:~/Source/some-proj/src$ teleport -o some-proj
sjohnson@corellia:~/Source/some-proj/src$ 
<... START NEW TERMINAL ...>
sjohnson@corellia:~$ . ./teleport -o some-proj
sjohnson@corellia:~/Source/some-proj/obj$
4

2 回答 2

5

问题是它getopts必须保持一点状态,以便可以在循环中调用它,而您并没有清除该状态。每次调用它时,它都会再处理一个参数,并且它会增加 shell 的OPTIND变量,以便在下次调用它时知道要处理哪个参数。完成所有参数后,每次调用它都会返回 1 (false),这会导致while退出。

第一次获取脚本时,它会按预期工作。第二次(和第三次,第四次......)时间,getopts除了返回 false 什么都不做。

在开始循环之前添加一行以重置状态:

unset OPTIND   # clear state so getopts will start over
while getopts "o:s:" opt
do
    # ...
done

(我假设您的成绩单中有错字,因为它显示您在第二次尝试时调用了脚本——而不是采购它,但这不是真正的问题。)

于 2011-07-14T01:59:42.373 回答
2

问题是您第一次调用是在获取脚本(这就是“. ./teleport”)在当前 shell 中运行脚本从而保留 cd。第二次调用它时,它没有源,所以你创建一个子shell,cd到适当的目录,然后退出子shell,让你回到你调用脚本的地方!

使这项工作的方法是简单地在当前 shell 中(即在脚本之外)制作 teleportToSrc 和 teleportToObj 别名或函数

于 2011-07-13T22:21:55.607 回答