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

use*_*621 7 unix bash shell macos

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

我意识到在 Mac OS (Snow Leopard) 上的登录 shell中$0解析为-bash这可能会破坏在 Linux 环境中正常工作的某些 shell 脚本*.

不幸的是,联机帮助页没有提到这个事实

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

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

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

Gil*_*il' 6

减号是系统告诉 shell 它是作为登录 shell 调用的方式,它应该提供源~/.profile(对于 Bourne 兼容的 shell)。在 Linux、OSX 和其他所有 Unix 上都是如此。脚本不会在登录 shell 中运行。对于脚本,$0是脚本文件的名称(带或不带完整路径)。

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

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

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

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

也许对参数零的一些解释是合适的。执行程序时,最终execve会发生系统调用。该系统调用采用三个参数:

  1. 一个文件名,它必须指定一个现有的可执行文件。内核加载这个文件并将执行转移到它。

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

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

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

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