gpt4 book ai didi

linux - 使用点空格与点斜线执行文件

转载 作者:太空宇宙 更新时间:2023-11-04 11:51:23 25 4
gpt4 key购买 nike

我正在尝试使用现有的代码库,但遇到了问题。简而言之,我执行了一个 shell 脚本(我们称之为 A),它的第一幕 是调用另一个脚本(B)。脚本 B 在我的当前目录中(我正在使用的程序的要求)。该软件的手册引用了 bash,但是 A 中的注释表明它是在 ksh 中开发的。到目前为止,我一直在 bash 中操作。

A 中,执行 B 的行很简单:

. B

它使用“点空间”语法来调用程序。它不会像 sudo 那样做任何不寻常的事情。

当我在没有点空格语法的情况下调用 A 时,即:

./A

它总是报错说找不到文件 B。我添加了 pwdlswhoamiecho $SHELLecho $PATHA 的行进行调试并确认 B 实际上就在那里,脚本运行时使用与我相同的 $SHELL命令提示符,脚本与我是同一用户,并且脚本具有与我相同的搜索路径 $PATH。我也验证了我是否这样做:

. B

在命令行中,它工作得很好。但是,如果我将 A 中的语法更改为:

./B

相反,A 会成功执行。

类似地,如果我用点空格语法执行A,那么两个。 B./B 工作。

总结:
./A 仅在 A 包含 ./B 语法时有效。
。 A 适用于 A./B。 B语法。

我知道使用点空间(即 .A)语法可以在不 fork 到子 shell 的情况下执行,但我不明白这会如何导致我观察到的行为显然就在那里。关于语法或父/子进程工作区的细微差别,我是否遗漏了什么?魔法?

UPDATE1:添加的信息表明脚本可能是在 ksh 中开发的,而我正在使用 bash
UPDATE2:添加了检查以验证 $PATH 是否相同。

UPDATE3:脚本说它是为 ksh 编写的,但它在 bash 中运行。针对 Kenster 的回答,我发现先运行 bash -posix 然后再运行 。 B 在命令行失败。这表明命令行和脚本之间的环境差异在于后者以 POSIX 兼容模式运行 bash,而命令行不是。仔细观察,我在 bash man 页面中看到了这个:

When invoked as sh, bash enters posix mode after the startup files are read.

Ashebang 确实是#!/bin/sh

总而言之,当我在没有点空格语法的情况下运行 A 时,它会 fork 到它自己的子 shell,它处于 POSIX 兼容模式,因为 shebang #!/bin/sh(而不是例如 #!/bin/bash。这是导致 A 的命令行和脚本运行时环境之间的关键区别 无法找到 B

最佳答案

让我们从命令路径如何工作以及何时使用开始。当您运行如下命令时:

ls /tmp

ls这里不包含/字符,因此 shell 在命令路径(PATH 环境变量的值)中的目录中搜索名为 ls 的文件.如果它找到一个,它就执行那个文件。在ls的情况下, 通常在 /bin/usr/bin ,这两个目录通常都在您的路径中。

当您在命令字中发出带有/的命令时:

/bin/ls /tmp

shell 不搜索命令路径。它专门查找文件 /bin/ls并执行它。

正在运行 ./A是运行名称中带有/的命令的示例。 shell 不搜索命令路径;它专门查找名为 ./A 的文件并执行它。 “。”是您当前工作目录的简写,所以 ./A指的是应该位于当前工作目录中的文件。如果该文件存在,它将像任何其他命令一样运行。例如:

cd /bin
./ls

可以运行 /bin/ls .

正在运行 . A是一个采购文件的例子。源文件必须是包含 shell 命令的文本文件。它由当前 shell 执行,无需启动新进程。要获取的文件的查找方式与查找命令的方式相同。如果文件名包含/,则 shell 会读取您指定的特定文件。如果文件名不包含/,则 shell 会在命令路径中查找它。

. A        # Looks for A using the command path, so might source /bin/A for example
. ./A # Specifically sources ./A

因此,您的脚本尝试执行 . B并没有声称 B不存在,即使有一个名为 B 的文件就在您当前的目录中。如上所述,shell 会在您的命令路径中搜索 B。因为B不包含任何/字符。搜索命令时,shell 不会自动搜索当前目录。如果该目录是命令路径的一部分,它只会搜索当前目录。

简而言之,. B可能会失败,因为您没有“。” (当前目录)在您的命令路径中,以及试图获取源代码的脚本 B假设“。”是你道路的一部分。在我看来,这是脚本中的错误。很多人运行时没有“。”在他们的路径中,脚本不应依赖于此。

编辑:

你说脚本使用了ksh , 当你使用 bash . Ksh 遵循 POSIX 标准——实际上,KSH 是 POSIX 标准的基础——并且总是按照我描述的那样搜索命令路径。 Bash 有一个名为“POSIX 模式”的标志,它控制它遵循 POSIX 标准的严格程度。当不处于 POSIX 模式时——这是人们通常使用它的方式——如果在命令路径中找不到文件,bash 将检查当前目录以查找要获取的文件。

如果你要运行 bash -posix然后运行 ​​. B在那个 bash 实例中,您应该会发现它不起作用。

关于linux - 使用点空格与点斜线执行文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56010462/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com