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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 12:51:44  来源:igfitidea点击:

How to get script directory in POSIX sh?

bashposixsh

提问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_SOURCEis $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 DIRto dirin 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/nullin the original command: $CDPATHis set to a null string so as to ensure that cdnever echoesanything.

请注意,我在下面的片段中已更改DIRdir,因为最好不要使用全大写的变量名称,以避免与环境变量和特殊的 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 -Pto the pwdcommand:

如果您还想生成的目录路径解析为最终目标,以防目录和/或其组件是symlinks,请添加-Ppwd命令中:

    # 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 foois symlinked to /usr/local/bin/fooin 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 readlinkis not a POSIX utility.
While BSD platforms, including macOS, have a readlinkutility too, on macOS it doesn't support -f's functionality. That said, to show how simple the task becomes ifreadlink -fis 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 -edoesand 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) readlinkutility - 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 commandto 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 as sh).
  • 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 $0to the shell executable name/path (except in zsh, where, as noted $0is truly the current script's path). By contrast (except in zsh), a script being sourced from another scriptthat itself was directly invoked, contains thatscript's path in $0.
  • To solve these problems, bash, ksh, and zshhave nonstandardfeaturesthat doallow determining the actual script path even in sourced scenarios and also detecting whether a script is being sourced or not; for instance, in bash, $BASH_SOURCEalwayscontains 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(除了 in zsh,其中,正如所指出的,$0是真正的当前脚本的路径)。相比之下(在 中除外zsh),源自另一个本身被直接调用的脚本的脚本在 中包含脚本的路径$0
  • 为了解决这些问题,bashksh,和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 -Ptwice is redundant - it's sufficient to use it with pwd.
    • The command is missing silencing of cd's potential stdout output, if $CDPATHhappens to be set.)
  • command -v -- "$0"
    • command -v -- "$0"is designed to cover one additional scenario: if the script is being sourcedfrom an interactiveshell, $0typically contains the mere filenameof the shell executable (sh), in which case dirnamewould simply return .(because that's what dirnameinvariably does when given a argument without a pathcomponent). command -v -- "$0"then returns that shell's absolute path through a $PATHlookup (/bin/sh). Note, however, that loginshells on some platforms (e.g., OSX) have their filename prefixed with -in $0(-sh), in which case command -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 as shon a given system: bash, ksh, and zshreturn an empty string; only dashechoes $0
        The POSIX spec. for commanddoesn't explicitly say whether command -v, when applied to a filesystem path, should only return executable files- which is what bash, ksh, and zshdo - but you can argue that it is implied by the very purpose of command; curiously, dash, which is usually the most compliant POSIX citizen, is deviating from the standard here. By contrast, kshis 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 in dash.
    • Given that the script's directory cannotbe determined when the script is being sourced- because $0then doesn't contain that information (except in zsh, which doesn't usually act as sh) - 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 $0directly: [ "$0" = "sh" ] || [ "$0" = "-sh" ] || [ "$0" = "/bin/sh" ]
      • However, even that doesn't work if the script is being sourced from anotherscript (that was itself directlyinvoked), because $0then simply contains the sourcingscript's path.
    • 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), $dirends up either containing ., if the shell executable was invoked as a mere filename (applying dirnameto 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), $0contains thatscript's path, and the script being sourced has no way of telling whether that's the case.
  • (两个旁白:
    • 使用-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、什么kshzsh做什么——但你可以争辩说,它的目的是暗示command; 奇怪的dash是,通常是最符合 POSIX 公民的 ,偏离了这里的标准。相比之下,ksh是这里唯一的模范公民,因为它是唯一一个仅报告可执行文件按照规范要求使用绝对(尽管未规范化)路径报告它们的模型。
      • 如果脚本可执行的,但不在 中$PATH,并且调用使用其文件名(例如,sh myScript),command -v -- "$0"则还将返回空字符串,除了 in dash
    • 考虑到脚本的目录不能脚本被当确定采购-因为$0再没有包含该信息(除zsh,它通常不作为sh) -有没有很好的解决了这个问题。
      • 返回该行解释器可执行的在这种情况下的目录路径存在一定的局限性-它,毕竟,没有脚本的目录-也许除了日后使用中的路径测试,以确定是否脚本正在采购。
        • 更可靠的方法是简单地$0直接测试:[ "$0" = "sh" ] || [ "$0" = "-sh" ] || [ "$0" = "/bin/sh" ]
      • 但是,如果脚本来自另一个脚本(它本身被直接调用),即使它也不起作用,因为$0它只包含脚本的路径。
    • 鉴于command -v -- "$0"来源场景的有限用处以及它打破了两个来源场景的事实,我的投票是不使用它,这给我们留下了:
      • 所有-sourced场景覆盖。
      • 调用中,您无法确定脚本的路径,并且充其量,在有限的情况下,您可以检测是否正在发生:
        • 当由 shell直接获取时(例如来自 shell 配置文件/初始化文件),如果 shell 可执行文件被作为纯粹的文件名调用(应用于纯粹的文件名总是返回),或者 shell 可执行文件的目录路径,则$dir最终包含. 无法可靠地区分来自当前目录的非来源调用。.dirname..
        • 当来自另一个脚本(它本身也不是源)时,$0包含脚本的路径,并且被获取的脚本无法判断是否是这种情况。


Background information:

背景资料:

POSIXdefines the behavior of $0with respect to shell scriptshere.

POSIX这里定义了关于 shell脚本行为$0

Essentially, $0should reflect the path of the script file as specified, which implies:

本质上,$0应该反映指定的脚本文件的路径,这意味着:

  • Do NOT rely on $0containing an absolutepath.
  • $0contains 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 transforms myScriptinto an absolute path and then executes it; e.g.:
      • myScript # executes /home/jdoe/bin/myScript, for instance
  • In all other cases, $0will reflect the script path as specified:

    • When explicitly invoking shwith 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).
  • 不要依赖$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 zshall exhibit this behavior.

在实践中bashdashksh、 和zsh都表现出这种行为。

By contrast, POSIX does NOT mandate the value of $0when 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 $0when your script is being sourced and expect standardized behavior.
    • In practice, bash, dash, and kshleave $0untouchedwhen sourcing scripts, meaning that $0contains the caller's$0value, or, more accurately, the $0value of the most recent caller in the call chain that hasn't been sourced itself; thus, $0may 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, $0will 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 $0to the current script's path is.
  • If you do need to handle this situation, you must identify the specific shell at hand and access its specificnon-standard features:
    • bash, ksh, and zshall offer their ownways of obtaining the running script's path, even when it's being sourced.
  • 因此,$0当您的脚本被获取并期望标准化行为时,您不能盲目使用。
    • 在实践中,bashdash,和ksh离开$0不变采购脚本时,这意味着$0包含主叫方的$0价值,或者更准确的说,$0最近在一直没有采购本身的调用链调用者的价值; 因此,$0可以指向 shell 的可执行文件或指向当前脚本的另一个(直接调用的)脚本的路径。
    • 相比之下,zsh作为唯一的异议者,实际上确实报告了当前脚本的路径$0。相反,$0将不提供有关脚本是否来源的指示。
    • 简而言之:仅使用 POSIX 功能,您既不能可靠地判断手头的脚本是否正在获取,也不能确定手头脚本的路径是什么,也不能$0确定与当前脚本路径的关系。
  • 如果确实需要处理这种情况,则必须确定手头的特定 shell 并访问其特定的非标准功能
    • bash, ksh, 和zsh所有这些都提供了自己的获取正在运行的脚本路径的方法,即使它是被获取的。

For the sake of completeness: the value of $0in othercontexts:

为了完整起见:其他上下文中$0

  • Inside a shell function, POSIX mandates that $0remain unchanged; therefore, whatever value it has outsidethe function, it'll have insideas well.
    • In practice, bash, dash, and kshdo behave that way.
    • Again, zshis the lone dissenter and reports the function'sname.
  • In a shell that accepted a command string via the -coptionon 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, and zshall behave that way.
  • Otherwise, in a shell notexecuting a script file, $0is 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, $0reports -bash, not bash, in interactive shells on OSX.
    • a shell that reads commands from stdin
      • this also applies to piping a script file to the shell via stdin (e.g., sh < myScript)
    • bash, dash, ksh, and zshall behave that way.
  • 在 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
    • 标准输入读取命令的外壳
      • 这也适用于通过标准输入将脚本文件传送到 shell(例如,sh < myScript
    • 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 $OLDPWDpre-cdexports the value for the duration of the one change directory (note: cdcan have residual effects on hashtables, but the only shabout which i am aware that actually males any good use of these is kevin ahlmquists - and since herbert xu - dash, and maybe some bsdstuff, but what do i know?)but does not carry over any cdexports as a result of the change.

在一个更改目录的持续时间内设置$OLDPWDcd导出值(注意:cd可能会对hash表格产生残余影响,但sh我知道实际上男性对这些有任何好处的唯一原因是 kevin ahlmquists - 并且因为 Herbert xu - dash,也许还有一些bsd东西,但我知道什么?)但不会cd因更改而结转任何出口。

thus, $OLDPWDdoes not change, actually, and if it had any value at all this remains as was. $PWDis changed as a result of the first cd, and the value becomes /dev/fd/0which points to /proc/self/fd, where a list of file descriptors for our process should be in ., to include whatever $0is on ./2.

因此,$OLDPWD实际上并没有改变,如果它有任何价值,它仍然保持原样。$PWD作为第一个的结果改变了cd,值变成/dev/fd/0which 指向/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!

好极了!