diff --git a/src/parse_execution.rs b/src/parse_execution.rs index 102404e01..5e92a09af 100644 --- a/src/parse_execution.rs +++ b/src/parse_execution.rs @@ -33,7 +33,10 @@ WILDCARD_ERR_MSG, }; use crate::parse_tree::{LineCounter, NodeRef, ParsedSourceRef}; -use crate::parse_util::parse_util_unescape_wildcards; +use crate::parse_util::{ + parse_util_locate_cmdsubst_range, parse_util_unescape_wildcards, + MaybeParentheses::CommandSubstitution, +}; use crate::parser::{Block, BlockData, BlockId, BlockType, LoopStatus, Parser, ProfileItem}; use crate::parser_keywords::parser_keywords_is_subcommand; use crate::path::{path_as_implicit_cd, path_try_get_path}; @@ -1471,9 +1474,10 @@ fn determine_redirections( ctx, None, ); + if !target_expanded || target.is_empty() { // TODO: Improve this error message. - return report_error!( + let error_ret = report_error!( self, ctx, STATUS_INVALID_ARGS, @@ -1481,6 +1485,23 @@ fn determine_redirections( "Invalid redirection target: %ls", target ); + if oper.mode == RedirectionMode::input && { + let redir_unexpanded = self.node_source(redir_node); + redir_unexpanded.starts_with(L!("<(")) + && match parse_util_locate_cmdsubst_range( + &redir_unexpanded[1..], + &mut 0, + false, + None, + None, + ) { + CommandSubstitution(p) => p.start() == 0, + _ => false, + } + } { + eprintf!("If you wish to use process substitution, consider the psub command, see: `help psub`\n"); + } + return error_ret; } // Make a redirection spec from the redirect token. diff --git a/tests/checks/psub.fish b/tests/checks/psub.fish index 5d5874f5b..830fbff50 100644 --- a/tests/checks/psub.fish +++ b/tests/checks/psub.fish @@ -59,3 +59,22 @@ end set -l diffs (comm -3 (__fish_print_help psub 2>| psub) (psub -hs banana 2>| psub)) test -z "$diffs" + +# In cases that look like process substitutions, mention psub. + +echo <(seq 0) +# CHECKERR: {{.*}}/psub.fish (line {{\d+}}): Invalid redirection target: +# CHECKERR: echo <(seq 0) +# CHECKERR: ^~~~~~~^ +# CHECKERR: If you wish to use process substitution, consider the psub command, see: `help psub` + +# To-do: should also mention psub here. +echo <(seq 1) +# CHECKERR: warning: An error occurred while redirecting file '1' +# CHECKERR: warning: Path '1' does not exist + +echo <(seq 2) +# CHECKERR: {{.*}}/psub.fish (line {{\d+}}): Invalid redirection target: +# CHECKERR: echo <(seq 2) +# CHECKERR: ^~~~~~~^ +# CHECKERR: If you wish to use process substitution, consider the psub command, see: `help psub`