Shell脚本在第二次运行时使用第一次运行的参数

时间:2010-06-29 13:56:02

标签: shell ksh

我在Korn Shell中运行,并尝试运行我写的一个简单的chdb脚本。如果在没有参数的情况下运行,它会提示用户输入数据库列表并等待选择。如果使用单个数字参数调用,它将自动为用户进行选择。

示例:

> . chdb
Select the database sid from the following:
  1) testdb1
  2) testdb2
  3) testdb3

Selection: 2 <-- user entered

Environment is now set up for testdb2.
>. chdb 2
Environment is now set up for testdb2.
>

我的问题是,当我使用上面的参数运行脚本,然后尝试再次运行它而没有参数时,它仍然使用旧的参数。

示例:

> . chdb 2
Environment is now set up for testdb2.
> . chdb
Environment is now set up for testdb2.
>
编辑:我正在使用点,因为我在环境中设置变量而不想调用子shell实例,否则数据库设置将无法工作。我有一种感觉,这可能是我的问题的根源,但我不知道如何解决它。

可能值得一提的另一件事是,使用至少一个参数调用我的脚本将始终按预期工作。除非在没有参数的情况下调用它,否则它永远不会使用先前输入的参数。

4 个答案:

答案 0 :(得分:1)

尝试:在input=$arg之后,执行unset arg或引用if [["$#" -ne "1"]]

答案 1 :(得分:1)

如果您使用带有'。'的脚本要设置环境变量,那么您在该脚本中声明的任何变量都将自动为全局变量,并传递给调用shell的会话。

有三种方法可以隔离变量并使它们成为非持久变量:

<强> 1。初始化变量

如果您使用单个变量来捕获用户选择,例如DBSELECTION,无论是在命令行上传递还是在交互模式下输入,您都可以通过将该变量初始化为空字符串来启动脚本;

DBSELECTION=""
if [ "$1ZZZ" != "ZZZ" ] ; then 
    DBSELECTION=$1
else
    interactiveMode
fi

- 其中“interactiveMode”是您定义的获取用户选择的过程。当然,您的方法或功能名称可能会有所不同。

<强> 2。取消设置变量

如果您正在使用临时变量来注册用户选择 - 如上面的DBSELECTION,您可能希望在脚本末尾取消设置变量;

DBSELECTION=""
if [ "$1ZZZ" != "ZZZ" ] ; then 
    DBSELECTION=$1
else
    interactiveMode
fi
unset DBSELECTION

第3。定义本地变量而不是全局变量

如果您正在使用临时变量,那么在本地(使用排版)而不是全局定义它们可能更为明智,这样它们就不会超出定义它们的函数。

typeset DBSELECTION=""
if [ "$1ZZZ" != "ZZZ" ] ; then 
    DBSELECTION=$1
else
    interactiveMode
fi

通过这种方式,ksh将为您处理变量,而不是自己明确地取消它。

答案 2 :(得分:0)

此外 - 您正在运行代码'sourced',这意味着当您再次运行时,脚本中声明的所有环境变量仍然存在。

尝试

./ chdb

而不是

。 chdb

答案 3 :(得分:0)

我找到了解决这个问题的方法。我在脚本的末尾添加了set --,以便取消设置所有参数。

对于其他遇到同样问题的人,set --会清除所有参数($ 1,$ 2,$ 3等)。使用shift仅删除第一个($ 1),或shift num取消设置第一个num参数。由此得出shift $#也将清除所有论点。