为什么 GNU Readline 的 shell-expand-line 命令只扩展第一个出现的波浪号 (~)?

Shu*_*eng 9 bash readline

根据 Bash 手册,shell-expand-lineGNU Readline 命令应该扩展命令行,就像 Bash 通常所做的那样,包括别名和历史扩展。

当前设置可以通过以下方式查看bind -P | grep shell-expand-line

shell-expand-line can be found on "\e\C-e".
Run Code Online (Sandbox Code Playgroud)

我的问题是~在下面的示例中只展开了第一个波浪号 ( ):

~/foo/bar ~/foo/baz
Run Code Online (Sandbox Code Playgroud)

按“\e\Ce”后:

/Users/nlykkei/foo/bar ~/foo/baz
Run Code Online (Sandbox Code Playgroud)

为什么?

mos*_*svy 6

如果你查看它的源代码,你会发现它shell-expand-line实际上应该被调用shell-expand-line-as-if-it-were-a-word

>> bashline.c
static int
shell_expand_line (count, ignore)
     int count, ignore;
{
     ...
      w->word = savestring (rl_line_buffer);
      w->flags = rl_explicit_arg ? (W_NOPROCSUB|W_NOCOMSUB) : 0;
      expanded_string = expand_word (w, rl_explicit_arg ? Q_HERE_DOCUMENT : 0);
Run Code Online (Sandbox Code Playgroud)
>>> subst.c
/* Expand WORD, performing word splitting on the result.  This does
   parameter expansion, command substitution, arithmetic expansion,
   word splitting, and quote removal. */

WORD_LIST *
expand_word (word, quoted)
     WORD_DESC *word;
     int quoted;
Run Code Online (Sandbox Code Playgroud)

请注意,该注释不包括文件名或波浪号扩展。所以它基本上是侥幸,它甚至适用于第一个波浪号(无论如何,波浪号只在单词的开头有意义)。但这也将进行过程替换,这也未提及。繁重的expand_word_internal工作在同一个文件中的函数中。

rl_explicit_arg一个片段中的意思是,如果您在键组合绑定到 之前按 Esc-1 或 Alt-2 shell-expand-line,则不会执行引号删除进程/命令替换。很直观,不是吗?

您可以尝试提交错误报告,但在 bash 中可能已经有数千个类似的限制和特殊情况。