2011-07-13 54 views
2

我有一个bash脚本,用于从当前位置的任何位置从源文件移动到bin目录(我将此脚本称为'teleport')。由于它基本上只是一个荣耀的'cd'命令,我必须在当前shell(即./teleport.sh)中运行它。我在.bashrc文件中设置了一个别名,以便'teleport'匹配'。 teleport.sh”。无法在当前环境中多次运行BASH脚本

我第一次运行它,它工作正常。但是,如果我在运行一次后再运行它,它什么都不会做。如果我关闭我的终端,然后再打开一个新终端,但只有第一次,它会再次运行。我的直觉是,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 

我对它的用法是一样的东西:

[email protected]:~$ cd /usr/local/src 
[email protected]:/usr/local/src$ . ./teleport -s some-proj 
[email protected]:~/Source/some-proj/src$ teleport -o some-proj 
[email protected]:~/Source/some-proj/src$ 
<... START NEW TERMINAL ...> 
[email protected]:~$ . ./teleport -o some-proj 
[email protected]:~/Source/some-proj/obj$ 

回答

5

的问题是,getopts必然保持状态的一点点,以便它可以被循环调用,并且你没有清除那个状态。每次调用它时,它会处理一个参数,并且它会增加shell的OPTIND变量,以便它知道下次调用哪个参数时进行处理。当它完成所有参数时,每次调用时都会返回1(假),这会使while退出。

第一次输入脚本时,它按预期工作。第二(和第三,第四...)时间,getopts不做任何事情,但返回false。

添加一行开始循环之前复位状态:

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

(我假设有一个在你的成绩单一个错字,因为它表明你调用脚本 - 不采购它 - 在第二尝试,但这不是真正的问题。)

+0

完美工作,谢谢Rob! – jwir3

2

的问题是,你第一次打电话是要采购的脚本(那是什么”。 ./teleport“)会在当前shell中运行脚本,从而保留cd。第二次调用它时,它不是源代码,所以你创建了一个子shell,cd到相应的目录,然后退出subshel​​l,让你回到你调用脚本的地方!

,使这项工作的方法就是让teleportToSrc和teleportToObj别名或函数在当前shell(即外部的脚本)

+0

那么,为什么第二次没有脚本来源?我想我可以制作这些别名......不知道为什么我决定让它们成为剧本。 – jwir3

+0

即使我做'。 。/ teleport'后调用一次(根据你的最后一个评论我应该认为它应该来源),它仍然不执行所需的功能。 – jwir3