Skip to content

How to get current process invocation name (argv[0]/$0)? (login shell on *nix) #30212

@rjmholt

Description

@rjmholt

I'm working to enable PowerShell as a login shell on *nix in PowerShell/PowerShell#10050.

When -Login or -l is passed, this works fine (we exec /bin/sh and then exec pwsh again).

But the convention in many *nix environments for login shells is to prepend a - onto the process name when it is exec'd (e.g. bash sees its own process name as -bash and then deduces it must run login shell logic).

With PowerShell as a .NET Core 3.0 application, I don't know how to access this information.

I've tried the args in public static int Main(string[] args), Environment.GetCommandLineArgs() and Process.GetCurrentProcess():

public static int Main(string[] args)
{
            Console.WriteLine("ARGS");
            foreach (string arg in args)
            {
                Console.WriteLine(arg);
            }
            Console.WriteLine("ENVIRONMENT ARGS");
            foreach (string arg in Environment.GetCommandLineArgs())
            {
                Console.WriteLine(arg);
            }
            Console.WriteLine($"PROCESS NAME: {System.Diagnostics.Process.GetCurrentProcess().ProcessName}");
...
}

Which from PowerShell prints when started as the default login shell on macOS:

ARGS
ENVIRONMENT ARGS
/Users/rjmholt/Documents/Dev/Microsoft/PowerShell/src/powershell-unix/bin/Debug/netcoreapp3.0/osx-x64/publish/pwsh.dll
PROCESS NAME: pwsh

Writing a small C program to show the same (compiled with cc ex.c):

#include <stdio.h>

int main(int argc, char **argv)
{
    for (int i = 0; i < argc; i++)
    {
	printf("%d: %s\n", i, argv[i]);
    }
}

When started as a login shell, prints:

0: -a.out

The mechanism for this seems to be the login util, which prepends the - before exec-ing the given executable.

My question is: is there a way to detect the name with which a process has been started? Ideally we could do this performantly, since it's a startup time thing and we just want to detect it as fast as possible so we can exec another process.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions