Skip to content

How to redirect stderr but continue to pipe stdout? #10271

Closed
@bobhy

Description

@bobhy

Question

I'm having trouble invoking an external command and redirecting stderr (to /dev/null) while piping stdout to the next step.
Maybe there's some other kind of redirection I should be using? Maybe it's a bug?

Sample:

> sudo apt update  | filter {|line| $line | str contains --ignore-case "can be upgraded" } 

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

╭───┬──────────────────────────────────────────────────────────────────────╮
│ 0 │ 6 packages can be upgraded. Run 'apt list --upgradable' to see them. │
│   │                                                                      │
╰───┴──────────────────────────────────────────────────────────────────────╯

Almost what I want, except for the ugly WARNING that didn't flow into the pipe.

(try to) Fix it by redirecting stderr:

> sudo apt update  err> /dev/null | filter {|line| $line | str contains --ignore-case "can be upgraded" } 
Hit:1 http://us.archive.ubuntu.com/ubuntu lunar InRelease
Hit:2 http://us.archive.ubuntu.com/ubuntu lunar-updates InRelease                                                      
Hit:3 http://packages.microsoft.com/repos/code stable InRelease                                                        
Hit:4 http://us.archive.ubuntu.com/ubuntu lunar-backports InRelease                                                    
Hit:5 https://packages.microsoft.com/repos/edge stable InRelease                                                       
Hit:6 http://security.ubuntu.com/ubuntu lunar-security InRelease           
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
6 packages can be upgraded. Run 'apt list --upgradable' to see them.

Does suppress the WARNING, but now filter isn't getting any input...

At first I though this had something to do with sudo, but you can repro with nonprivileged external dir command

> dir -l .  argle  | filter {|x| $x | str contains Music}
dir: cannot access 'argle': No such file or directory
╭───┬────────────────────────────────────────────────────────╮
│ 0 │ .:                                                     │
│   │ total 89                                               │
│   │ drwxr-xr-x 2 bobhy bobhy   2 Aug 18 21:12 Desktop      │
│   │ drwxr-xr-x 2 bobhy bobhy   3 Sep  6 14:20 Documents    │
│   │ drwxr-xr-x 2 bobhy bobhy  25 Sep  6 23:47 Downloads    │
│   │ drwxr-xr-x 2 bobhy bobhy   2 Aug 18 21:12 Music        │
│   │ drwxr-xr-x 3 bobhy bobhy   3 Aug 25 13:18 Pictures     │
│   │ drwxr-xr-x 2 bobhy bobhy   2 Aug 18 21:12 Public       │
│   │                                                        │
╰───┴────────────────────────────────────────────────────────╯

The missing directory error is reported to stderr as in the previous case.

I don't quite get why each newline-delimited line of output wasn't broken into a separate line item, like it seems to have done with sudo apt, but never mind: the key thing is filter returned a list with one element, as desired.

> dir -l .  argle err> /dev/null  | filter {|x| $x | str contains Music}
.:
total 89
drwxr-xr-x 2 bobhy bobhy   2 Aug 18 21:12 Desktop
drwxr-xr-x 2 bobhy bobhy   3 Sep  6 14:20 Documents
drwxr-xr-x 2 bobhy bobhy  25 Sep  6 23:47 Downloads
drwxr-xr-x 2 bobhy bobhy   2 Aug 18 21:12 Music
drwxr-xr-x 3 bobhy bobhy   3 Aug 25 13:18 Pictures
drwxr-xr-x 2 bobhy bobhy   2 Aug 18 21:12 Public

Note that the dir output isn't being piped into filter,at all, apparently.

Additional context and details

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionthe issue author asks somethingredirection-pipeAll related to redirection to files or more complex pipelines with STDERR

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions