我多年来一直是 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
设置为参数零。 它是login
、su
或任何处理登录的程序,它会选择传递给 shell 的参数,并在-
参数零前面添加一个,以告诉 shell 它是一个登录 shell。
也许有必要对参数零进行一些解释。当执行程序时,最终execve
会发生系统调用。该系统调用需要三个参数:
文件名,必须指定一个现有的可执行文件。内核加载此文件并将执行权移交给该文件。
一个字符串数组,称为参数。该数组中的元素零是按照惯例与上述相同的文件名,或者如果可执行文件的位置是通过搜索
$PATH
环境变量确定的,则仅使用不带完整路径的文件名。此惯例也有例外,例如登录 shell。另一个字符串数组,称为环境。
当您通过键入从 shell 调用程序时myprogram foo bar
,的参数为execve
:
1. (/usr/bin/myprogram
假设这是 shell 找到的位置myprogram
)
2. myprogram
,, 3. 对于每个导出的 shell 变量,变量名后跟等号和值。foo
bar
没有通用的方法来查找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 相同的问题。