bash 如何在 POSIX sh 中获取脚本目录?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29832037/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get script directory in POSIX sh?
提问by city
I have the following code in my bash script. Now I wanna use it in POSIX sh. How can I convert it?
我的 bash 脚本中有以下代码。现在我想在 POSIX sh 中使用它。我怎样才能转换它?
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" > /dev/null && pwd )"
回答by mklement0
The POSIX-shell (sh
) counterpart of $BASH_SOURCE
is $0
. see bottom for background info
的 POSIX-shell ( sh
) 对应物$BASH_SOURCE
是$0
。背景信息见底部
Caveat: The crucial difference is that if your script is being sourced(loaded into the currentshell with .
), the snippets below will notwork properly.explanation further below
警告:关键的区别在于,如果您的脚本正在被获取(使用 加载到当前shell 中.
),下面的代码片段将无法正常工作。下面进一步解释
Note that I've changed DIR
to dir
in the snippets below, because it's better not to use all-uppercase variable namesso as to avoid clashes with environment variables and special shell variables.
The CDPATH=
prefix takes the place of > /dev/null
in the original command: $CDPATH
is set to a null string so as to ensure that cd
never echoesanything.
请注意,我在下面的片段中已更改DIR
为dir
,因为最好不要使用全大写的变量名称,以避免与环境变量和特殊的 shell 变量发生冲突。
该CDPATH=
前缀需要的地方> /dev/null
在原来的命令:$CDPATH
被设置为空字符串,以确保cd
永远回响什么。
In the simplest case, this will do (the equivalent of the OP's command):
在最简单的情况下,这将执行(相当于 OP 的命令):
dir=$(CDPATH= cd -- "$(dirname -- "dir=$(CDPATH= cd -- "$(dirname -- "dir=$(dirname -- "$(rreadlink "rreadlink() ( # Execute the function in a *subshell* to localize variables and the effect of `cd`.
target= fname= targetDir= CDPATH=
# Try to make the execution environment as predictable as possible:
# All commands below are invoked via `command`, so we must make sure that `command`
# itself is not redefined as an alias or shell function.
# (Note that command is too inconsistent across shells, so we don't use it.)
# `command` is a *builtin* in bash, dash, ksh, zsh, and some platforms do not even have
# an external utility version of it (e.g, Ubuntu).
# `command` bypasses aliases and shell functions and also finds builtins
# in bash, dash, and ksh. In zsh, option POSIX_BUILTINS must be turned on for that
# to happen.
{ \unalias command; \unset -f command; } >/dev/null 2>&1
[ -n "$ZSH_VERSION" ] && options[POSIX_BUILTINS]=on # make zsh find *builtins* with `command` too.
while :; do # Resolve potential symlinks until the ultimate target is found.
[ -L "$target" ] || [ -e "$target" ] || { command printf '%s\n' "ERROR: '$target' does not exist." >&2; return 1; }
command cd "$(command dirname -- "$target")" # Change to target dir; necessary for correct resolution of target path.
fname=$(command basename -- "$target") # Extract filename.
[ "$fname" = '/' ] && fname='' # !! curiously, `basename /` returns '/'
if [ -L "$fname" ]; then
# Extract [next] target path, which may be defined
# *relative* to the symlink's own directory.
# Note: We parse `ls -l` output to find the symlink target
# which is the only POSIX-compliant, albeit somewhat fragile, way.
target=$(command ls -l "$fname")
target=${target#* -> }
continue # Resolve [next] symlink target.
fi
break # Ultimate target reached.
done
targetDir=$(command pwd -P) # Get canonical dir. path
# Output the ultimate target's canonical path.
# Note that we manually resolve paths ending in /. and /.. to make sure we have a normalized path.
if [ "$fname" = '.' ]; then
command printf '%s\n' "${targetDir%/}"
elif [ "$fname" = '..' ]; then
# Caveat: something like /var/.. will resolve to /private (assuming /var@ -> /private/var), i.e. the '..' is applied
# AFTER canonicalization.
command printf '%s\n' "$(command dirname -- "${targetDir}")"
else
command printf '%s\n' "${targetDir%/}/$fname"
fi
)
")")
")" && pwd -P)
")" && pwd)
If you also want to resolve the resultingdirectory path to its ultimate target in case the directory and/or its components are symlinks, add -P
to the pwd
command:
如果您还想将生成的目录路径解析为最终目标,以防目录和/或其组件是symlinks,请添加-P
到pwd
命令中:
# NOT recommended - see discussion below.
DIR=$( cd -P -- "$(dirname -- "$(command -v -- "DIR=$( cd -P -- "$(dirname -- "$(command -v -- "if OLDPWD=/dev/fd/0 \
cd - && ls -lLidFH ?
then cd . <8
fi </proc/self/fd 8<. 9<##代码##
")")" && pwd -P )
")")" && pwd -P )
Caveat: This is NOTthe same as finding the script's own true directory of origin:
Let's say your script foo
is symlinked to /usr/local/bin/foo
in the $PATH
, but its true path is /foodir/bin/foo
.
The above will still report /usr/local/bin
, because the symlink resolution (-P
) is applied to the directory, /usr/local/bin
, rather than to the script itself.
警告:这是不一样的发现脚本自身起源的真正目录:
比方说,你的脚本foo
被链接到/usr/local/bin/foo
的$PATH
,但其真正的路径/foodir/bin/foo
。
上面仍然会报告/usr/local/bin
,因为符号链接解析 ( -P
) 应用于目录, /usr/local/bin
,而不是脚本本身。
To find the script's own true directory of origin, you'd have to inspect the script'spath to see if it's a symlinkand, if so, follow the (chain of) symlinks to the ultimate target file, and then extract the directory path from the targetfile's canonical path.
要找到脚本自己的真实原始目录,您必须检查脚本的路径以查看它是否是符号链接,如果是,请遵循(链)符号链接到最终目标文件,然后从中提取目录路径该 目标文件的规范路径。
GNU's readlink -f
(better: readlink -e
) could do that for you, but readlink
is not a POSIX utility.
While BSD platforms, including macOS, have a readlink
utility too, on macOS it doesn't support -f
's functionality. That said, to show how simple the task becomes ifreadlink -f
is available: dir=$(dirname "$(readlink -f -- "$0")")
.
GNU 的readlink -f
(更好:)readlink -e
可以为您做到这一点,但readlink
它不是 POSIX 实用程序。
虽然 BSD 平台(包括 macOS)也有一个readlink
实用程序,但在 macOS 上它不支持-f
的功能。也就是说,为了显示任务变得多么简单,如果readlink -f
可用:dir=$(dirname "$(readlink -f -- "$0")")
。
In fact, there is noPOSIX utility for resolving filesymlinks. There are ways to work around that, but they're cumbersome and not fully robust:
事实上,没有用于解析文件符号链接的POSIX 实用程序。有一些方法可以解决这个问题,但它们很麻烦而且不完全健壮:
The following, POSIX-compliant shell functionimplements what GNU's readlink -e
doesand is a reasonably robust solutionthat only fails in two rare edge cases:
在下文中,符合POSIX标准的shell函数什么GNU的工具readlink -e
确实是一个相当强大的解决方案是唯一的失败有两种罕见的边缘情况:
- paths with embedded newlines(very rare)
- filenames containing literal string
->
(also rare)
- 带有嵌入换行符的路径(非常罕见)
- 包含文字字符串的文件名
->
(也很少见)
With this function, named rreadlink
, defined, the following determines the script's true directory path of origin:
使用这个函数,named rreadlink
,定义,下面的内容确定了脚本的真实目录路径:
Note: If you're willing to assume the presence of a (non-POSIX) readlink
utility - which would cover macOS, FreeBSD and Linux - a similar, but simpler solution can be found in this answerto a related question.
注意:如果您愿意假设存在(非 POSIX)readlink
实用程序 - 它将涵盖 macOS、FreeBSD 和 Linux - 一个类似但更简单的解决方案可以在这个相关问题的答案中找到。
rreadlink()
source code- place beforecalls to itin scripts:
rreadlink()
源代码-在脚本中调用它之前放置:
To be robust and predictable, the function uses command
to ensure that only shell builtins or external utilities are called (ignores overloads in the forms of aliases and functions).
It's been tested in recent versions of the following shells: bash
, dash
, ksh
, zsh
.
为了健壮和可预测,该函数用于command
确保仅调用 shell 内置函数或外部实用程序(忽略别名和函数形式的重载)。
它已在以下 shell 的最新版本中进行了测试:bash
, dash
, ksh
, zsh
。
How to handle sourcedinvocations:
如何处理源调用:
tl;dr:
tl;博士:
Using POSIX features only:
仅使用POSIX 功能:
- You cannotdetermine the script's pathin a sourcedinvocation(except in
zsh
, which, however, doesn't usually act assh
). - You can detect whether or notyour script is being sourced ONLY if your script is being sourced directlyby the shell(such as in a shell profile/initialization file; possibly via a chainof sourcings), by comparing
$0
to the shell executable name/path (except inzsh
, where, as noted$0
is truly the current script's path). By contrast (except inzsh
), a script being sourced from another scriptthat itself was directly invoked, contains thatscript's path in$0
. - To solve these problems,
bash
,ksh
, andzsh
have nonstandardfeaturesthat doallow determining the actual script path even in sourced scenarios and also detecting whether a script is being sourced or not; for instance, inbash
,$BASH_SOURCE
alwayscontains the running script's path, whether it's being sourced or not, and[[ $0 != "$BASH_SOURCE" ]]
can be used to test whether the script is being sourced.
- 您无法在源调用中确定脚本的路径(除了 in
zsh
,但是,它通常不充当sh
)。 - 通过与 shell 可执行文件名称/路径进行比较,您可以仅在脚本直接由 shell 获取时(例如在 shell 配置文件/初始化文件中;可能通过源链)来检测脚本是否被获取
$0
(除了 inzsh
,其中,正如所指出的,$0
是真正的当前脚本的路径)。相比之下(在 中除外zsh
),源自另一个本身被直接调用的脚本的脚本在 中包含该脚本的路径$0
。 - 为了解决这些问题,
bash
,ksh
,和zsh
具有非标准特征在于做允许确定实际脚本路径即使在源场景和还检测脚本是否正在来源与否; 例如,在bash
,$BASH_SOURCE
总是包含了运行脚本的路径,无论是正在采购或没有,[[ $0 != "$BASH_SOURCE" ]]
剧本是否正在来源可用于测试。
To show why this cannot be done, let's analyze the command from Walter A's answer:
为了说明为什么不能这样做,让我们分析一下Walter A 的回答中的命令:
##代码##- (Two asides:
- Using
-P
twice is redundant - it's sufficient to use it withpwd
. - The command is missing silencing of
cd
's potential stdout output, if$CDPATH
happens to be set.)
- Using
command -v -- "$0"
command -v -- "$0"
is designed to cover one additional scenario: if the script is being sourcedfrom an interactiveshell,$0
typically contains the mere filenameof the shell executable (sh
), in which casedirname
would simply return.
(because that's whatdirname
invariably does when given a argument without a pathcomponent).command -v -- "$0"
then returns that shell's absolute path through a$PATH
lookup (/bin/sh
). Note, however, that loginshells on some platforms (e.g., OSX) have their filename prefixed with-
in$0
(-sh
), in which casecommand -v -- "$0"
doesn't work as intended (returns an empty string).- Conversely,
command -v -- "$0"
can misbehave in two non-sourced scenariosin which the shell executable,sh
, is directlyinvoked, with the script as an argument:- if the script itself is notexecutable:
command -v -- "$0"
may return an empty string, depending on what specific shell acts assh
on a given system:bash
,ksh
, andzsh
return an empty string; onlydash
echoes$0
The POSIX spec. forcommand
doesn't explicitly say whethercommand -v
, when applied to a filesystem path, should only return executable files- which is whatbash
,ksh
, andzsh
do - but you can argue that it is implied by the very purpose ofcommand
; curiously,dash
, which is usually the most compliant POSIX citizen, is deviating from the standard here. By contrast,ksh
is the lone model citizen here, because it is the only one that reports executable files only andreports them with an absolute(albeit not normalized) path, as the spec requires. - if the script isexecutable, but not in the
$PATH
, and the invocation uses its mere filename(e.g.,sh myScript
),command -v -- "$0"
will also return the empty string, except indash
.
- if the script itself is notexecutable:
- Given that the script's directory cannotbe determined when the script is being sourced- because
$0
then doesn't contain that information (except inzsh
, which doesn't usually act assh
) - there's no good solution to this problem.- Returning the shell executable'sdirectory path in that situation is of limited use - it is, after all, not the script'sdirectory - except perhaps to later use that path in a testto determine whether or notthe script is being sourced.
- A more reliable approach would be to simply test
$0
directly:[ "$0" = "sh" ] || [ "$0" = "-sh" ] || [ "$0" = "/bin/sh" ]
- A more reliable approach would be to simply test
- However, even that doesn't work if the script is being sourced from anotherscript (that was itself directlyinvoked), because
$0
then simply contains the sourcingscript's path.
- Returning the shell executable'sdirectory path in that situation is of limited use - it is, after all, not the script'sdirectory - except perhaps to later use that path in a testto determine whether or notthe script is being sourced.
- Given the limited usefulness of
command -v -- "$0"
in sourced scenarios and the fact that it breaks two non-sourced scenarios, my vote is for NOT using it, which leaves us with:- All non-sourced scenarios arecovered.
- In sourcedinvocations, you cannot determine the script's path, and at best, in limited circumstances, you can detect whether or notsourcing is occurring:
- When sourced directlyby the shell (such as from a shell profile/initialization file),
$dir
ends up either containing.
, if the shell executable was invoked as a mere filename (applyingdirname
to a mere filename alwaysreturns.
), or the shell executable's directory path otherwise..
cannot be reliably distinguished from a non-sourced invocation from the current directory. - When sourced from another script(that was itself not also sourced),
$0
contains thatscript's path, and the script being sourced has no way of telling whether that's the case.
- When sourced directlyby the shell (such as from a shell profile/initialization file),
- (两个旁白:
- 使用
-P
两次是多余的 - 将它与pwd
. cd
如果$CDPATH
碰巧设置了该命令,则缺少对潜在标准输出的静音。)
- 使用
command -v -- "$0"
command -v -- "$0"
旨在覆盖一个额外的场景:如果脚本正在采购从交互式外壳,$0
通常包含单纯的文件名外壳可执行文件(的sh
),在这种情况下dirname
会简单地返回.
(因为那是什么的dirname
总是它时提供的参数没有路径成分)。command -v -- "$0"
然后通过$PATH
查找 (/bin/sh
)返回该 shell 的绝对路径。但是请注意,某些平台(例如 OSX)上的登录shell 的文件名以-
in$0
(-sh
)为前缀,在这种情况下command -v -- "$0"
,无法按预期工作(返回空字符串)。- 相反,
command -v -- "$0"
在两种非源场景中可能会出现错误行为,在这些场景中sh
,直接调用shell 可执行文件 ,并将脚本作为参数:- 如果脚本本身不可执行:
command -v -- "$0"
可能返回一个空字符串,这取决于特定的 shellsh
在给定系统上的作用:bash
,ksh
,并zsh
返回一个空字符串;只有dash
呼应$0
的POSIX规范。forcommand
没有明确说明command -v
,当应用于文件系统路径时,是否应该只返回可执行文件——这是什么bash
、什么ksh
和zsh
做什么——但你可以争辩说,它的目的是暗示command
; 奇怪的dash
是,通常是最符合 POSIX 公民的 ,偏离了这里的标准。相比之下,ksh
是这里唯一的模范公民,因为它是唯一一个仅报告可执行文件并按照规范要求使用绝对(尽管未规范化)路径报告它们的模型。 - 如果脚本是可执行的,但不在 中
$PATH
,并且调用仅使用其文件名(例如,sh myScript
),command -v -- "$0"
则还将返回空字符串,除了 indash
。
- 如果脚本本身不可执行:
- 考虑到脚本的目录不能脚本被当确定采购-因为
$0
再没有包含该信息(除zsh
,它通常不作为sh
) -有没有很好的解决了这个问题。- 返回该行解释器可执行的在这种情况下的目录路径存在一定的局限性-它,毕竟,没有脚本的目录-也许除了日后使用中的路径测试,以确定是否脚本正在采购。
- 更可靠的方法是简单地
$0
直接测试:[ "$0" = "sh" ] || [ "$0" = "-sh" ] || [ "$0" = "/bin/sh" ]
- 更可靠的方法是简单地
- 但是,如果脚本来自另一个脚本(它本身被直接调用),即使它也不起作用,因为
$0
它只包含源脚本的路径。
- 返回该行解释器可执行的在这种情况下的目录路径存在一定的局限性-它,毕竟,没有脚本的目录-也许除了日后使用中的路径测试,以确定是否脚本正在采购。
- 鉴于
command -v -- "$0"
来源场景的有限用处以及它打破了两个非来源场景的事实,我的投票是不使用它,这给我们留下了:- 所有非-sourced场景被覆盖。
- 在源调用中,您无法确定脚本的路径,并且充其量,在有限的情况下,您可以检测源是否正在发生:
- 当由 shell直接获取时(例如来自 shell 配置文件/初始化文件),如果 shell 可执行文件被作为纯粹的文件名调用(应用于纯粹的文件名总是返回),或者 shell 可执行文件的目录路径,则
$dir
最终包含. 无法可靠地区分来自当前目录的非来源调用。.
dirname
.
.
- 当来自另一个脚本(它本身也不是源)时,
$0
包含该脚本的路径,并且被获取的脚本无法判断是否是这种情况。
- 当由 shell直接获取时(例如来自 shell 配置文件/初始化文件),如果 shell 可执行文件被作为纯粹的文件名调用(应用于纯粹的文件名总是返回),或者 shell 可执行文件的目录路径,则
Background information:
背景资料:
POSIXdefines the behavior of $0
with respect to shell scriptshere.
POSIX在这里定义了关于 shell脚本的行为$0
。
Essentially, $0
should reflect the path of the script file as specified, which implies:
本质上,$0
应该反映指定的脚本文件的路径,这意味着:
- Do NOT rely on
$0
containing an absolutepath. $0
contains an absolutepathonly if:- you explicitlyspecify an absolutepath; e.g.:
~/bin/myScript
(assuming the script itself is executable)sh ~/bin/myScript
- you invoke an executable script by mere filename, which requires that it both be executable andin the
$PATH
; behind the scenes, the system transformsmyScript
into an absolute path and then executes it; e.g.:myScript # executes /home/jdoe/bin/myScript, for instance
- you explicitlyspecify an absolutepath; e.g.:
In all other cases,
$0
will reflect the script path as specified:- When explicitly invoking
sh
with a script, this can be a mere filename(e.g.,sh myScript
) or a relative path(e.g.,sh ./myScript
) - When invoking an executable script directly, this can be a relativepath (e.g.,
./myScript
- note that a mere filenamewould only find scripts in the$PATH
).
- When explicitly invoking
- 不要依赖
$0
包含绝对路径。 $0
仅在以下情况下才包含绝对路径:- 您明确指定了绝对路径;例如:
~/bin/myScript
(假设脚本本身是可执行的)sh ~/bin/myScript
- 您仅通过filename调用可执行脚本,这要求它既是可执行的又在
$PATH
; 在幕后,系统转化myScript
为绝对路径,然后执行;例如:myScript # executes /home/jdoe/bin/myScript, for instance
- 您明确指定了绝对路径;例如:
在所有其他情况下,
$0
将反映指定的脚本路径:- 当
sh
使用脚本显式调用时,这可以是单纯的文件名(例如,sh myScript
)或相对路径(例如,sh ./myScript
) - 当调用可执行脚本直接,这可以是一个相对路径(例如,
./myScript
-注意,一个单纯的文件名只找到脚本中$PATH
)。
- 当
In practice, bash
, dash
, ksh
, and zsh
all exhibit this behavior.
在实践中bash
,dash
、ksh
、 和zsh
都表现出这种行为。
By contrast, POSIX does NOT mandate the value of $0
when sourcinga script(using the special built-in utility .
("dot")), so you cannot rely on it, and, in practice, behavior differs across shells.
相比之下,POSIX 不强制要求获取脚本$0
时的值(使用特殊的内置实用程序.
(“点”)),因此您不能依赖它,并且在实践中,不同 shell 的行为不同。
- Thus, you cannot blindly use
$0
when your script is being sourced and expect standardized behavior.- In practice,
bash
,dash
, andksh
leave$0
untouchedwhen sourcing scripts, meaning that$0
contains the caller's$0
value, or, more accurately, the$0
value of the most recent caller in the call chain that hasn't been sourced itself; thus,$0
may point either to the shell's executable or to the path of another(directly invoked) script that sourced the current one. - By contrast,
zsh
, as the lone dissenter, actually doesreport the currentscript's path in$0
. Conversely,$0
will provide no indication as to whether the script is being sourced or not. - In short: using POSIX features only, you can neither tell reliably whether the script at hand is being sourced, nor what the script at hand's path is, nor what the relationship of
$0
to the current script's path is.
- In practice,
- If you do need to handle this situation, you must identify the specific shell at hand and access its specificnon-standard features:
bash
,ksh
, andzsh
all offer their ownways of obtaining the running script's path, even when it's being sourced.
- 因此,
$0
当您的脚本被获取并期望标准化行为时,您不能盲目使用。- 在实践中,
bash
,dash
,和ksh
离开$0
不变采购脚本时,这意味着$0
包含主叫方的$0
价值,或者更准确的说,$0
最近在一直没有采购本身的调用链调用者的价值; 因此,$0
可以指向 shell 的可执行文件或指向当前脚本的另一个(直接调用的)脚本的路径。 - 相比之下,
zsh
作为唯一的异议者,实际上确实报告了当前脚本的路径$0
。相反,$0
将不提供有关脚本是否来源的指示。 - 简而言之:仅使用 POSIX 功能,您既不能可靠地判断手头的脚本是否正在获取,也不能确定手头脚本的路径是什么,也不能
$0
确定与当前脚本路径的关系。
- 在实践中,
- 如果确实需要处理这种情况,则必须确定手头的特定 shell 并访问其特定的非标准功能:
bash
,ksh
, 和zsh
所有这些都提供了自己的获取正在运行的脚本路径的方法,即使它是被获取的。
For the sake of completeness: the value of $0
in othercontexts:
为了完整起见:在其他上下文中的值$0
:
- Inside a shell function, POSIX mandates that
$0
remain unchanged; therefore, whatever value it has outsidethe function, it'll have insideas well.- In practice,
bash
,dash
, andksh
do behave that way. - Again,
zsh
is the lone dissenter and reports the function'sname.
- In practice,
- In a shell that accepted a command string via the
-c
optionon startup, it's the first operand(non-option argument) that sets$0
; e.g.:sh -c 'echo \$0: $0 \$1: $1' foo one # -> '$0: foo $1: one'
bash
,dash
,ksh
, andzsh
all behave that way.
- Otherwise, in a shell notexecuting a script file,
$0
is the value of the first argument that the shell's parent processpassed- typically, that's the shell'sname or path (e.g.sh
, or/bin/sh
); this includes:- an interactiveshell
- Caveat: some platforms, notably OSX, always create loginshells when creating interactive shells, and prepend
-
to the shell name before placing it in$0
, so as to signal to the shell that it is a _login shell; thus, by default,$0
reports-bash
, notbash
, in interactive shells on OSX.
- Caveat: some platforms, notably OSX, always create loginshells when creating interactive shells, and prepend
- a shell that reads commands from stdin
- this also applies to piping a script file to the shell via stdin (e.g.,
sh < myScript
)
- this also applies to piping a script file to the shell via stdin (e.g.,
bash
,dash
,ksh
, andzsh
all behave that way.
- an interactiveshell
- 在 shell函数中,POSIX 指令
$0
保持不变;因此,无论它在函数外有什么值,在函数内也有。- 在实践中,
bash
,dash
, 和ksh
确实如此表现。 - 再次,
zsh
是唯一的异议者并报告函数的名称。
- 在实践中,
- 在启动时通过
-c
选项接受命令字符串的 shell 中,它是设置;的第一个操作数(非选项参数)$0
。例如:sh -c 'echo \$0: $0 \$1: $1' foo one # -> '$0: foo $1: one'
bash
,dash
,ksh
, 和zsh
所有行为都是这样。
- 否则,在外壳不执行脚本文件,
$0
是第一个参数的,所述壳的所述值父进程传递-典型地,这就是外壳的名称或路径(例如sh
,或/bin/sh
); 这包括:- 一个交互式的壳
- 警告:一些平台,特别是 OSX,在创建交互式 shell 时总是创建登录shell,并在将它放入 之前在 shell 名称前加上,
-
以便向 shell 发出$0
信号,它是一个 _login shell;因此,默认情况下,在 OSX 上的交互式 shell 中$0
报告-bash
,而不是bash
。
- 警告:一些平台,特别是 OSX,在创建交互式 shell 时总是创建登录shell,并在将它放入 之前在 shell 名称前加上,
- 从标准输入读取命令的外壳
- 这也适用于通过标准输入将脚本文件传送到 shell(例如,
sh < myScript
)
- 这也适用于通过标准输入将脚本文件传送到 shell(例如,
bash
,dash
,ksh
, 和zsh
所有行为都是这样。
- 一个交互式的壳
回答by Walter A
@City responded that
@City 回应说
##代码##works. I used it too.
I found the command at https://stackoverflow.com/questions/760110/can-i-get-the-absolute-path-to-the-cu??rrent-script-in-kornshell.
作品。我也用过。
我在https://stackoverflow.com/questions/760110/can-i-get-the-absolute-path-to-the-cu??rrent-script-in-kornshell找到了该命令。
回答by mikeserv
there. that should enable you to change directpry through some magic links as file descriptors.
那里。这应该使您能够通过一些魔术链接作为文件描述符更改 directpry。
setting $OLDPWD
pre-cd
exports the value for the duration of the one change directory (note: cd
can have residual effects on hash
tables, but the only sh
about which i am aware that actually males any good use of these is kevin ahlmquists - and since herbert xu - dash
, and maybe some bsd
stuff, but what do i know?)but does not carry over any cd
exports as a result of the change.
在一个更改目录的持续时间内设置$OLDPWD
预cd
导出值(注意:cd
可能会对hash
表格产生残余影响,但sh
我知道实际上男性对这些有任何好处的唯一原因是 kevin ahlmquists - 并且因为 Herbert xu - dash
,也许还有一些bsd
东西,但我知道什么?)但不会cd
因更改而结转任何出口。
thus, $OLDPWD
does not change, actually, and if it had any value at all this remains as was. $PWD
is changed as a result of the first cd
, and the value becomes /dev/fd/0
which points to /proc/self/fd
, where a list of file descriptors for our process should be in .
, to include whatever $0
is on ./2
.
因此,$OLDPWD
实际上并没有改变,如果它有任何价值,它仍然保持原样。$PWD
作为第一个的结果改变了cd
,值变成/dev/fd/0
which 指向/proc/self/fd
我们进程的文件描述符列表应该在的地方.
,以包括任何$0
在./2
.
so we do an ls ... ?
and have a look at all of the wonderful info we can get, and we go whence we came.
所以我们做了ls ... ?
一个,看看我们能得到的所有精彩信息,然后我们就去我们来的地方。
yay!
好极了!