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

发布于 2024-09-07 11:13:01 字数 734 浏览 8 评论 0原文

我正在 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 实例,否则数据库设置将无法工作。我有一种感觉,这可能是我的问题的根源,但我不知道如何解决它。

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

I am operating in a Korn Shell, and attempting to run a simple chdb script I wrote. If run with no arguments, it prompts the user with a list of databases and waits for a selection. If called with a single numeric argument, it will automatically make the selection for the user.

Example:

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

My problem is that when I run the script with an argument as above, and then try to run it again with no arguments, it still uses the old arguments.

Example:

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

EDIT: I am using the dot because I am setting variables in the environment and do not want to invoke a child shell instance, otherwise the database setup won't work. I have a feeling this may be the source of my problem, but I am not sure how to work around it.

One other thing that might be worth mentioning is that calling my script with at least 1 argument will always work as intended. It never uses previously entered arguments unless it is invoked with no parameters.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

帅气称霸 2024-09-14 11:13:01

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

Try: after input=$arg, doing an unset arg, or quote if [["$#" -ne "1"]]

夜清冷一曲。 2024-09-14 11:13:01

如果您使用带有“.”的脚本设置环境变量,那么您在该脚本中声明的任何变量都将自动成为全局变量,并传递到调用 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 将为您处理该变量,而不是您自己显式地取消设置。

If you're using a script with '.' to set environment variables, then any variables you declare in that script will automatically be global, and pass into the session of the invoking shell.

There are three approaches to isolate your variables and make them non-persistent:

1. Initialise Variables

If you're using a single variable to capture the user selection e.g. DBSELECTION, whether passed on the command line or entered in interactive mode, then you may wish to start your script by initialising that variable to an empty string;

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

-- where "interactiveMode" is your defined process for getting the user selection. Your method or function names may vary, of course.

2. Unset Variables

If you're using temporary variables to register the user selection - like the one above, DBSELECTION, you may want to unset the variable at the end of your script;

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

3. Define Local rather than Global Variables

If you're using temporary variables, it may be more advisable to define them locally (using typeset) instead of globally, so that they do not persist beyond the function within which they're defined.

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

In this way ksh will handle the variable for you, rather than explicitly unsetting it yourself.

宁愿没拥抱 2024-09-14 11:13:01

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

尝试使用

./chdb

而不是

. CHDB

Also - you are running the code 'sourced' which means all of the envrionment variables declared in the script are still there when you run it again.

Try

./chdb

instead of

. chdb

葬﹪忆之殇 2024-09-14 11:13:01

我想出了一个办法来处理这个问题。我在脚本末尾添加了 set -- ,以便它取消设置所有参数。

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

I figured out a way to handle this. I added set -- at the end of my script so that it unsets all of the arguments.

For anyone else having this same problem, set -- clears all of the arguments ($1, $2, $3 and so on). Use shift to only remove the first one ($1), or shift num to unset the first num arguments. It follows that shift $# will clear all arguments as well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文