Skip to content

Remove caret (^) as redirector for stderr #4394

@ThomasAH

Description

@ThomasAH

I propose removing the caret (^) as a redirector for stderr in fish 3.0.

Reason 1: This is surprising for users of other shells and may lead to data loss

There are many commands using the caret on the command line for special purposes, e.g. git (see #1873). While some special handling has been introduced to reduce the need for quoting (see Reason 2), this does not help in all cases, e.g. git log ^refA refB will create a file refA containing the error message of git.
Many other programs use ^, too, for me the most notable problem is grep.
I often use the command dpkg -l|grep -v ^ii to check for problems with not fully installed or purged Debian packages. In fish this prints nothing, and grep's error message is sent to the new file ii.
Or I use ps auxww|grep ^theuser to quickly find processes of some users.
Or grep ^http someconfigfile to see if the config file contains a setting about httpserver or httpproxy or ...

While this often just results in a stray file (which is already bad enough), this can easily overwrite existing files, because sometimes I am looking for something where a file of the same name exists, e.g. Makefile targets (which luckily can often be rebuilt), or filtered output of ls, e.g. ls | grep -v ^README to show me everything but README (which is now overwritten) and various README.foo files. Or ls | grep -v ^access.log | grep -v ^error.log to hide the current and rotated web server log files and see what other files are present. Yes, I could add quotes and I should add a backslash in front of the dot in the regexp, but I really don't expect a file accessblog here, so I don't do it in interactive use.

Reason 2: Workarounds have been introduced, but they introduce even more surprising behavior.

To workaround the problem in git (#1873), the handling of ^ was changed to be different than the handling of >, so echo foo^bar prints foo^bar, but echo foo ^ bar prints foo and creates an empty file bar. This is different from e.g. echo foo>bar and echo foo > bar which both do the same thing.

The need for this workaround indicates that using the caret as a redirection character is problematic.

Reason 3: The law of orthogonality (https://fishshell.com/docs/current/design.html#ortho)

^ is just a shortcut for 2>, so this syntax saves only a single character.
The user still has to know the difference between stdout and stderr to use this feature.
The user still has to know about file descriptors to redirect both, stdout and stderr, to the same file with echo Hello > all_output.txt ^&1.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions