The option: -d curl conveys the data in the request body using the application/x-www-form-urlencoded content type which is one of the supported ways of sending those parameters in OAuth2.
-d Sends the specified data in a POST request to the HTTP server, in the same way that a browser does when a user has filled in an HTML form and presses the submit button. This will cause curl to pass the data to the server using the content-type application/x-www-form-urlencoded.
In the Salesforce code you're installing the correct content type, but then are sending the OAuth2 related parameters as additional headers instead of sending them in the request body.
You need to update the code to send the parameters in the request body using the application/x-www-form-urlencoded encoding.