为什么 Mac 上的“$0”中有一个减号?

为什么 Mac 上的“$0”中有一个减号?

我多年来一直是 GNU/Linux 用户,但我不知道如何在 Mac 上获取可用的进程信息。

我意识到这$0已解析-bash为 Mac OS(Snow Leopard)上的登录 shell。这可能会破坏在 Linux 环境中运行良好的某些 shell 脚本*.

不幸的是,手册页没有提到这个事实

如果使用命令文件调用 bash,则 $0 设置为该文件的名称。如果使用 -c 选项启动 bash,则 $0 设置为要执行的字符串后的第一个参数(如果存在)。否则,它设置为用于调用 bash 的文件名,如参数零所示。

减号有特殊含义吗? 有没有什么类似的东西/proc或命令行工具可以帮助我找到相关的可执行文件?

* 我真傻。当然,$0 将计算为脚本名称,如手册中所述

答案1

减号是系统告诉 shell 它被调用为登录 shell 并且它应该执行 source 操作的方式~/.profile(对于兼容 Bourne 的 shell)。这在 Linux、OSX 和所有其他 unix 上都是正确的。脚本不会在登录 shell 中运行。对于脚本,$0是脚本文件的名称(带或不带完整路径)。

添加:手册页确实解释了(几乎所有)不同的情况:

  • “如果使用命令文件调用 bash,则 $0 将设置为该文件的名称。”这涵盖使用 执行的脚本bash myscript,以及直接执行脚本并以 开头的间接情况#!/bin/bash

  • “如果 bash 以 -c 选项启动,则 $0 将设置为要执行的字符串后的第一个参数(如果存在)。” 使用-c,则$0设置为调用者明确指示的任何内容。

  • “否则,它将被设置为用于调用 bash 的文件名,由参数零给出。” 登录 shell 属于这种情况:除了参数零之外,没有其他参数来调用 shell,因此$0设置为参数零。 它是loginsu或任何处理登录的程序,它会选择传递给 shell 的参数,并在-参数零前面添加一个,以告诉 shell 它是一个登录 shell。

也许有必要对参数零进行一些解释。当执行程序时,最终execve会发生系统调用。该系统调用需要三个参数:

  1. 文件名,必须指定一个现有的可执行文件。内核加载此文件并将执行权移交给该文件。

  2. 一个字符串数组,称为参数。该数组中的元素零是按照惯例与上述相同的文件名,或者如果可执行文件的位置是通过搜索$PATH环境变量确定的,则仅使用不带完整路径的文件名。此惯例也有例外,例如登录 shell。

  3. 另一个字符串数组,称为环境。

当您通过键入从 shell 调用程序时myprogram foo bar,的参数为execve
    1. (/usr/bin/myprogram假设这是 shell 找到的位置myprogram
    2. myprogram,,     3. 对于每个导出的 shell 变量,变量名后跟等号和值。foobar

没有通用的方法来查找execve从正在运行的程序传递到的可执行文件的名称。在 Linux 下,它通常可用,因为进程 ID 在/proc/$$/exe哪里$$。每个 unix 都使其可用,ps但内部工作原理ps差异很大。可执行文件可能会在程序运行时被删除或重命名;在这种情况下ps可能会报告过时的信息或没有信息。

答案2

man bash

exec [-cl] [-a name] [command [arguments]]
如果指定了 command,它将替换 shell。不会创建新进程。参数将成为 command 的参数。如果提供了 -l 选项,shell 会在传递给 command 的第零个参数的开头放置一个破折号。这就是 login(1) 所做的。...

答案3

我不确定 -bash 发生了什么,但如果你在 shell 中再次运行 bash,$0 的值似乎没问题。

这似乎是 os x 所做的特殊操作,因为如果您运行 /usr/bin/login(这是终端程序使用的默认脚本),则会出现与 $0 相同的问题。

相关内容