-
-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
improve stdin detection on Windows #643
Comments
I don't know PowerShell, but from my point of view, your command doesn't really make sense. It seems like you're trying to pipe text into ripgrep to search, but you're still using the If ripgrep is having a problem detecting that it should search stdin, you might consider trying Otherwise, you might need to wait for someone who understands PowerShell to respond to this. Sorry. |
You are right, the first sample doesn't make sense. I didn't notice it because I discovered that I was quickly started following the "pipe" problem. It is really question here for anyone with deep inside about how that in PowerShell works. No problem with ripgrep, just asking here. |
@stej Did you try using |
@BurntSushi just |
@stej Instead of I otherwise don't know how to read your screenshots. Can you interpret them for me? |
After I reread your comments, I realized that I really did simplify the examples too much. It's probably needed do invoke rg in inner pipeline. Environment: Commands and results:
Note that the string goes really into the pipeline and is standard string as expected.
I tried the |
Ah, this is pretty interesting. It's probably the pipe in front of the powershell command.
|
I'm still finding it very hard to interpret your comments. I can't tell which commands are running as expected for you and which you think are wrong. For example, To answer your question about
The first command recursively searches the entire current directory for the pattern Now observe these commands:
Ideally, they are equivalent, in that they both search the stdin content This behavior works reliably on UNIX, but there have been issues on Windows. This is why I've suggested that you use |
I'm sorry for lack of detail. I'll try to describe the previous commands in more detail. The command On the other hand the commnad At the beginning it's good to note that usually people use PowerShell in interactive mode. Reading pipeline input in PowerShell:
first command outputs 3 numbers to stdout. The second command somehow catches all the stdin input, converts it to string and sends to output. I shown the way how to consume pipeline input in powershell -- it's via More comples command:
prints a number every second in green color. It is artifical of course, because it could be all done in one command. So the first command And the second command reads the numbers from input (via Now back to the example with echo and rg
Echo sends something to pipe. It is sent to PowerShell, which should execute command |
Why is that surprising? That sounds correct to me. Why are you piping In any case, if you want to force ripgrep to search the current directory, then just tell it to do that. |
@stej can you give a simple example of the command you want to run, and what you want it to output? It's kind of hard to understand what you're trying to do and where you think the problem is. for example, EDIT: guess you've given a couple, but the intent or point is still unclear I guess. |
Example: We have some log files that contain bunch of errors. Some files have almost no errors, some have large number (>= 5). And we need to find all logged in users from the files with large number of errors. Example file where I don't want to search in:
Example file that I need to inspect for all logged in users:
The command I would use (split for readability):
On one line:
Result: Workaround:
and the command outputs
|
@stej Thanks, that's much better. I agree with you that this is a bug. However, I don't know how to fix it. Someone with more Windows knowledge needs to either teach me or submit a PR themselves. I can outline the problem though. ripgrep uses a fair bit of logic to determine what things it should search. This method collects all of the file paths (including Lines 367 to 386 in 1aec4b1
Since no explicit file paths are given, ripgrep falls back to grabbing a collection of "default" paths. Mostly, this is a matter of determining whether to search the current working directory, or stdin: Lines 388 to 404 in 1aec4b1
This logic is necessary to differentiate commands like Since our set of file paths is empty, we can distill this logic down to two checks. Is there a tty on stdin? Is stdin readable? In your case, my guess is that ripgrep correctly determines that there is no tty on stdin (if there was, it would then search the CWD). Which means it falls down to Lines 993 to 1004 in 1aec4b1
But on Windows is implemented like this: Lines 1006 to 1012 in 1aec4b1
We default to |
The Windows equivalent of that Unix code uses GetFileType,
|
Note that WSL's tty is notable not implemented as a console, so functions like |
A somewhat idiomatic powershell solution would look something like this: class LineMatch{
[int] $Line
[string] $Text
[string] ToString() { return "{0}: {1}" -f $this.Line, $this.Text}
}
class FileMatch{
[string] $Path
[System.Collections.Generic.List[LineMatch]] $Lines = [System.Collections.Generic.List[LineMatch]]::new()
[string] ToString() {return $this.Path}
}
function Get-RGMatch {
[OutputType([FileMatch])]
param(
[Parameter(Mandatory)]
[string] $Pattern
)
$rgoutput = rg --heading --line-number $Pattern
switch -regex($rgoutput){
'^[^\d]\w' {
$p = [FileMatch] @{
Path=$_
}
continue
}
'^(\d+):(.*)' {
$line = [LineMatch] @{
Line=[int]$matches.1
Text=$matches.2
}
$p.Lines.Add($line)
continue
}
'^\s*$' {
$p
$p=$null
continue
}
default {Write-Warning "$_"}
}
$p
}
Get-RGMatch 'class' | where Count -gt 5 | sort Path | format-table -AutoSize It would basically parse the ripgrep output and create objects of the output.
|
#848 Is a feature request to make that parsing more straight forward and cheaper. |
@powercode Could you please state more clearly what you're trying to say? It sounds like you're trying to help someone write a better PowerShell script, but I don't see how that fixes the bug here? |
This commit updates the CHANGELOG to reflect all the work done to make libripgrep a reality. * Closes #162 (libripgrep) * Closes #176 (multiline search) * Closes #188 (opt-in PCRE2 support) * Closes #244 (JSON output) * Closes #416 (Windows CRLF support) * Closes #917 (trim prefix whitespace) * Closes #993 (add --null-data flag) * Closes #997 (--passthru works with --replace) * Fixes #2 (memory maps and context handling work) * Fixes #200 (ripgrep stops when pipe is closed) * Fixes #389 (more intuitive `-w/--word-regexp`) * Fixes #643 (detection of stdin on Windows is better) * Fixes #441, Fixes #690, Fixes #980 (empty matching lines are weird) * Fixes #764 (coalesce color escapes) * Fixes #922 (memory maps failing is no big deal) * Fixes #937 (color escapes no longer used for empty matches) * Fixes #940 (--passthru does not impact exit status) * Fixes #1013 (show runtime CPU features in --version output)
This commit updates the CHANGELOG to reflect all the work done to make libripgrep a reality. * Closes #162 (libripgrep) * Closes #176 (multiline search) * Closes #188 (opt-in PCRE2 support) * Closes #244 (JSON output) * Closes #416 (Windows CRLF support) * Closes #917 (trim prefix whitespace) * Closes #993 (add --null-data flag) * Closes #997 (--passthru works with --replace) * Fixes #2 (memory maps and context handling work) * Fixes #200 (ripgrep stops when pipe is closed) * Fixes #389 (more intuitive `-w/--word-regexp`) * Fixes #643 (detection of stdin on Windows is better) * Fixes #441, Fixes #690, Fixes #980 (empty matching lines are weird) * Fixes #764 (coalesce color escapes) * Fixes #922 (memory maps failing is no big deal) * Fixes #937 (color escapes no longer used for empty matches) * Fixes #940 (--passthru does not impact exit status) * Fixes #1013 (show runtime CPU features in --version output)
Using version 0.6.0
I tried to parse some text and for each parsed term to call rg. Something like this (added newlines fo readibility):
However, this doesn't work. I'm able to get much more simple example like this:
echo a|powershell -command "d:\prgs\rg.exe -g 2017-10-18* test "
doesn't output anythingpowershell -command "d:\prgs\rg.exe -g 2017-10-18* test "
- searches for "test" as expected (not that only theecho a|
is missing there)Does anybody here any idea why rg doesn't work when called from PowerShell when something is sent through pipeline into PowerShell?
The text was updated successfully, but these errors were encountered: