Powershell: Calling the CLI from the outside with an empty command string (-c '') crashes PowerShell

Created on 2 Oct 2019  路  6Comments  路  Source: PowerShell/PowerShell

From _within_ PowerShell, running pwsh -c '' (pwsh -Command '') provides a helpful error message (followed by the CLI syntax):

Cannot process the command because of a missing parameter. A command must follow -Command.

By contrast, when pwsh is called _from the outside_, it _crashes_.

Steps to reproduce

Run from either cmd.exe or bash:

pwsh -c ""

Expected behavior

The following should print to stderr and a nonzero exit code should be reported, analogous to what happens when calling from PowerShell.

Cannot process the command because of a missing parameter. A command must follow -Command.

(CLI syntax diagram)

Actual behavior

The pwsh process crashes as follows:

Unhandled exception. System.ArgumentNullException: Value cannot be null. (Parameter 'value')
   at System.String.IndexOf(String value, Int32 startIndex, Int32 count, StringComparison comparisonType)
   at System.String.IndexOf(String value, StringComparison comparisonType)
   at Microsoft.PowerShell.CommandLineParameterParser.MatchSwitch(String switchKey, String match, String smallestUnambiguousMatch)
   at Microsoft.PowerShell.CommandLineParameterParser.EarlyParse(String[] args)
   at Microsoft.PowerShell.UnmanagedPSEntry.Start(String consoleFilePath, String[] args, Int32 argc)
   at Microsoft.PowerShell.ManagedPSEntry.Main(String[] args)

Environment data

PowerShell Core 7.0.0-preview.4
Issue-Bug Resolution-Answered WG-Engine

All 6 comments

@chuanjiao10 I think it is one issue.

@chuanjiao10:

Your original issue had a misconception about how POSIX-like shells such as Bash evaluate pwsh -c "$pid".

https://github.com/PowerShell/PowerShell/issues/10410#issuecomment-537570864 explains the misconception in detail and offers solutions.

In short: When you call from Bash, pwsh -c "$pid" is effectively the same as pwsh -c "", because _Bash_ expands $pid and - given that the variable doesn't exist - expands it to the empty string.

It is _only_ pwsh -c "" that is the problem - that is, passing what (ultimately evaluates to) an _empty string_ to -c (-Command) from _outside of PowerShell_ - and that's why this issue was created: to focus on the real problem.

This doesn't appear to crash on pwsh -c "" currently but the process exits with 0 with no helpful information.

pwsh -c, however, exits with a code of 64 and a message. The behavior of pwsh -c "" (empty argument) could be made more consistent with the behavior with no argument (and when invoked from inside of PowerShell).

The behavior of pwsh -c "" (empty argument) could be made more consistent with the behavior with no argument (and when invoked from inside of PowerShell).

But "" is valid command.

Agreed, @iSazonov.

On further reflection, I think I was wrong about the expected behavior in the OP:

Since an argument _is_ passed to -c in this case, the syntax requirements are met, so we shouldn't treat this the same as neglecting to pass an argument to -c.

After the "" are stripped by PowerShell's CLI, a verbatim empty string remains (as opposed to a string literal representing the empty string). This is effectively the _absence_ of any statement.

As a no-op, it is by definition successful, and the exit should be 0.
This is consistent with how POSIX-compatible shells handle this case.

Since the current preview already exhibits this behavior, I think we can close this issue.

Note that the only reason it behaves differently when called _from PowerShell_ is the broken handling of quoted arguments as described in #1995, which causes empty-string literals not to be passed at all, so that pwsh -c "" is unexpectedly the same as pwsh -c

Was this page helpful?
0 / 5 - 0 ratings