当 ksh 脚本源自另一个脚本时,它如何确定自身的完整路径?

发布于 2024-12-07 18:44:53 字数 369 浏览 0 评论 0原文

当脚本由 ksh 获取时,它如何确定它的路径?即

$ ksh ". foo.sh"

我在 stackoverflow 和其他地方发布的 BASH 中看到了非常好的方法,但尚未找到 ksh 方法。

使用“$0”不起作用。这仅指“ksh”。

更新:我尝试使用“历史记录”命令,但不知道当前脚本之外的历史记录。

$ cat k.ksh
#!/bin/ksh
. j.ksh
$ cat j.ksh
#!/bin/ksh
a=$(history | tail -1)
echo $a
$ ./k.ksh
270 ./k.ksh

我希望它回显“* ./j.ksh”。

How can a script determine it's path when it is sourced by ksh? i.e.

$ ksh ". foo.sh"

I've seen very nice ways of doing this in BASH posted on stackoverflow and elsewhere but haven't yet found a ksh method.

Using "$0" doesn't work. This simply refers to "ksh".

Update: I've tried using the "history" command but that isn't aware of the history outside the current script.

$ cat k.ksh
#!/bin/ksh
. j.ksh
$ cat j.ksh
#!/bin/ksh
a=$(history | tail -1)
echo $a
$ ./k.ksh
270 ./k.ksh

I would want it echo "* ./j.ksh".

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

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

发布评论

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

评论(4

若无相欠,怎会相见 2024-12-14 18:44:53

如果是 AT&T ksh93,则此信息存储在 .sh 命名空间中的变量 .sh.file 中。

示例

sourced.sh

(
 echo "Sourced: ${.sh.file}"
)

调用:

$ ksh -c '. ./sourced.sh'

结果:

Sourced: /var/tmp/sourced.sh

.sh.file 变量与 $0 不同。而 $0 可以是 ksh/usr/bin/ksh,或者当前运行脚本的名称 .sh.file 将始终引用当前范围的文件

在交互式 shell 中,该变量甚至不存在:

$ echo ${.sh.file:?}
-ksh: .sh.file: parameter not set

If it's the AT&T ksh93, this information is stored in the .sh namespace, in the variable .sh.file.

Example

sourced.sh:

(
 echo "Sourced: ${.sh.file}"
)

Invocation:

$ ksh -c '. ./sourced.sh'

Result:

Sourced: /var/tmp/sourced.sh

The .sh.file variable is distinct from $0. While $0 can be ksh or /usr/bin/ksh, or the name of the currently running script, .sh.file will always refer to the file for the current scope.

In an interactive shell, this variable won't even exist:

$ echo ${.sh.file:?}
-ksh: .sh.file: parameter not set
千と千尋 2024-12-14 18:44:53

我相信唯一的便携式解决方案是覆盖 source 命令:

source() {
  sourced=$1
  . "$1"
}

然后使用 source 而不是 . (脚本名称将位于 $sourced 中)。

I believe the only portable solution is to override the source command:

source() {
  sourced=$1
  . "$1"
}

And then use source instead of . (the script name will be in $sourced).

财迷小姐 2024-12-14 18:44:53

当然,采购和分叉之间的区别在于,采购导致被调用的脚本在调用进程中执行。 Henk 在 ksh93 中展示了一个优雅的解决方案,但如果像我一样,您被 ksh88 困住了,那么您需要一个替代方案。我不想通过使用 C-shell 语法来更改默认的 ksh 采购方法,并且在工作中这将违反我们的编码标准,因此创建和使用 source() 函数对我来说是行不通的。 ps, $0 和 $_ 不可靠,所以这里有一个替代方案:

$ cat b.sh ;猫 c.sh ; ./b.sh

#!/bin/ksh
export SCRIPT=c.sh
. $SCRIPT 
echo "PPID: $"
echo "FORKING c.sh"
./c.sh

如果我们在变量中设置调用的脚本,并使用该变量获取它,则该变量将可供调用的脚本使用,因为它们位于同一进程空间中。

#!/bin/ksh
arguments=$_
pid=$
echo "PID:$pid"
command=`ps -o args -p $pid | tail -1`
echo "COMMAND (from ps -o args of the PID): $command"
echo "COMMAND (from c.sh's \$_ ) : $arguments"
echo "\$SCRIPT variable: $SCRIPT"
echo dirname: `dirname $0`
echo ; echo

输出如下:

PID:21665
COMMAND (from ps -o args of the PID): /bin/ksh ./b.sh
COMMAND (from c.sh's $_ ) : SCRIPT=c.sh
$SCRIPT variable: c.sh
dirname: .


PPID: 21665
FORKING c.sh
PID:21669
COMMAND (from ps -o args of the PID): /bin/ksh ./c.sh
COMMAND (from c.sh's $_ ) : ./c.sh
$SCRIPT variable: c.sh
dirname: .

因此,当我们在调用者脚本中设置 SCRIPT 变量时,该变量可以从源脚本的操作数访问,或者,在分叉进程的情况下,该变量以及父进程的所有其他环境变量被复制给子进程。在任何一种情况下,SCRIPT 变量都可以包含您的命令和参数,并且在源和分叉的情况下都可以访问。

The difference of course between sourcing and forking is that sourcing results in the invoked script being executed within the calling process. Henk showed an elegant solution in ksh93, but if, like me, you're stuck with ksh88 then you need an alternative. I'd rather not change the default ksh method of sourcing by using C-shell syntax, and at work it would be against our coding standards, so creating and using a source() function would be unworkable for me. ps, $0 and $_ are unreliable, so here's an alternative:

$ cat b.sh ; cat c.sh ; ./b.sh

#!/bin/ksh
export SCRIPT=c.sh
. $SCRIPT 
echo "PPID: $"
echo "FORKING c.sh"
./c.sh

If we set the invoked script in a variable, and source it using the variable, that variable will be available to the invoked script, since they are in the same process space.

#!/bin/ksh
arguments=$_
pid=$
echo "PID:$pid"
command=`ps -o args -p $pid | tail -1`
echo "COMMAND (from ps -o args of the PID): $command"
echo "COMMAND (from c.sh's \$_ ) : $arguments"
echo "\$SCRIPT variable: $SCRIPT"
echo dirname: `dirname $0`
echo ; echo

Output is as follows:

PID:21665
COMMAND (from ps -o args of the PID): /bin/ksh ./b.sh
COMMAND (from c.sh's $_ ) : SCRIPT=c.sh
$SCRIPT variable: c.sh
dirname: .


PPID: 21665
FORKING c.sh
PID:21669
COMMAND (from ps -o args of the PID): /bin/ksh ./c.sh
COMMAND (from c.sh's $_ ) : ./c.sh
$SCRIPT variable: c.sh
dirname: .

So when we set the SCRIPT variable in the caller script, the variable is either accessible from the sourced script's operands, or, in the case of a forked process, the variable along with all other environment variables of the parent process are copied for the child process. In either case, the SCRIPT variable can contain your command and arguments, and will be accessible in the case of both sourcing and forking.

迷你仙 2024-12-14 18:44:53

您应该发现它是历史记录中的最后一个命令。

You should find it as last command in the history.

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