Search code examples
powershelltshark

Powershell has a problem escaping double quotes in tshark


In cmd

tshark -r a.pcapng -Y "http.request.uri == \"/test.php\" || http.response"

There is an error when using Escape / in Powershell. I tried \ ` , but I couldn't get the command to work.

tshark -r 0.pcapng -Y "http.request.uri == `"\/test.php`" || http.response"
tshark: "`" was unexpected in this context.
    http.request.uri == `\/test.php` || http.response
                        ^

Solution

  • The equivalent of the following cmd.exe command line:

    :: cmd.exe (batch file)
    tshark -r a.pcapng -Y "http.request.uri == \"/test.php\" || http.response"
    

    is (applies analogously to all calls to external programs):

    • in PowerShell (Core) 7 v7.3+:

      # PowerShell 7.3+
      tshark -r a.pcapng -Y "http.request.uri == `"/test.php`" || http.response"
      
      • That is, in order to embed " characters inside a "..." (expandable) string, you must escape them as `", i.e. using the so-called backtick, PowerShell's escape character.

        • Note: Since your call doesn't require expansion (string interpolation), you could switch to a '...' (verbatim) string in which case the embedded " don't require escaping:

          # PowerShell 7.3+
          tshark -r a.pcapng -Y 'http.request.uri == "/test.php" || http.response'
          
      • Behind the scenes, when calling an external program such as tshark, PowerShell (.NET) by default ensures that the embedded " is then escaped as \" when it constructs the process command line, because that's the form of escaping most widely used by CLIs on Windows.

        • This behavior is controlled by the $PSNativeCommandArgumentPassing preference variable, whose default value on Windows, 'Windows', makes selective exceptions for the sake of backward compatibility; you can disable these exceptions ('Standard'), or you can categorically opt into the old, broken behavior ('Legacy') - see next point.
    • In Windows PowerShell (the legacy, ships-with-Windows, Windows-only edition of PowerShell whose latest and last version is 5.1) and PowerShell (Core) 7 up to v7.2.x, the \-escaping for external programs must unfortunately be performed manually, potentially in addition to PowerShell's own escaping, due to a long-standing bug:

      # Windows PowerShell and PowerShell 7.2-
      tshark -r a.pcapng -Y "http.request.uri == \`"/test.php\`" || http.response"
      
      # With a verbatim string.
      tshark -r a.pcapng -Y 'http.request.uri == \"/test.php\" || http.response'
      

    See this answer for more information.