1

In this StackOverflow thread, the suggested answer is supplying magic "stdin" string '@-' to the command option.

# Create data as PS hashtable literal.
$data = @{ user = @{ name = "$Firstname $Lastname"; email = "$adUsername@mydomain.org" } }

# Convert to JSON with ConvertTo-Json and pipe to `curl` via *stdin* (-d '@-')
$data | ConvertTo-Json -Compress | curl.exe mydomain.zendesk.com/api/v2/users.json -d '@-' -H "Content-Type: application/json" -X POST -v -u myuser:mypass

It works like a charm, but what does the magic "stdin" string actually mean?

Thank you!

Toshi
  • 145
  • 1
  • 9

1 Answers1

4

curl's -d parameter optionally allows you to supply data via a file (its contents) rather than by direct value.

So as to distinguish direct values (the default) from a value representing a filename, filenames must be prefixed with @ (which is a common convention in the Unix world).

In the Unix world - is a frequently used convention to represent stdin (standard input) in contexts where filenames are expected (depending on context it may also represent stdout (standard output).

Thus, @- effectively instructs curl to read the -d argument from stdin, which in PowerShell is (always) provided via the pipeline (|).

In your PowerShell command @- must be quoted ('@-'), because an unquoted @ at the start of an argument is a metacharacter, i.e., a character with special syntactic meaning (it serves several functions, including splatting).
Alternatively, you could escape just the @ itself: `@- (PowerShell's escape character is `, the so-called backtick).

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • Thank you! Your explanation is very clear and educative. I wasn't aware that the `-d` argument can take a file. – Toshi Jun 18 '20 at 18:03
  • Glad to hear it, @Toshi; the `@` prefix for arguments representing filenames rather than direct values is a common convention in the Unix world. – mklement0 Jun 18 '20 at 18:10