如何使用“PS2”变量调整 Bash 的“scratch”别名?

如何使用“PS2”变量调整 Bash 的“scratch”别名?

很多时候,我需要快速输入一些字符行(例如为了简化数学表达式),然后丢弃整个内容。当然,我的文本编辑器通常有几个运行会话,我可以在那里进行。我也一直在使用以下系统;我echo "在终端中输入(运行 bash),然后输入任何内容;当我完成后,我输入一个结束语"

昨天,我决定在 my 中添加一些更优雅的内容,.bashrc并创建了以下别名:

# write junk on the terminal (stop with a line containing only "." )
# alias scratch="awk '/^\.$/{exit}'"
# alias scratch="sed -ne '/^\.$/q'"
alias scratch='grep -q "^\.$"'

您可以看到上面的三个变体执行相同的操作:我输入scratch,然后输入我想要输入的任何内容,最后以仅包含.(点)的行结束。

我对此非常满意,但我也想到了以下变体:

alias scratch="cat - > /dev/null << ."

>它在每行开头都有一个初始提示,执行相同的操作。

然后,我想知道如何使用PS2环境变量来更改此提示,但我无法让任何东西完全正常工作。当然,PS2完成后应该恢复当前提示。scratch如何仅在“临时”会话期间将别名的此变体的提示设置为任意字符串?

答案1

我不完全确定这有什么用(与 或您喜欢的任何编辑器相比nanovim,但是......它需要别名吗?

$ <<.
> foo
> bar
> baz
> .

只是"会更短,但会出现错误消息......

$ "
> oh
> ah
> ui
> "
bash: $'\noh\nah\nui\n': command not found

请注意,这些东西并没有真正消失......

$ history
  497  <<.
foo
bar
baz
.

如果这让您感到困扰,请先禁用历史记录或随后清除它。

对于自定义 PS2 提示符来说,这很困难,因为(至少对于 Bash 而言)它必须设置为父 shell。如果您将其设置在子 shell 中,它将被忽略。您可以通过启动一个显式的 shell 实例来解决这个问题,如下所示...

$ PS1=@_ PS2=:_ bash --norc
@_<<.
:_hey
:_.
@_exit
$

但在这一点上,编写一个专用的暂存和丢弃程序会更有意义。

不同的方法,根本不使用 PS2 提示符:

$ while read -p ":-> " ; do : ; done
:-> hey
:-> how 
:-> do

只是你不能使用“.”离开这里。好吧,您可以轻松地将其添加为条件......

$ alias scratch='(var=_; while read -r -p ":-> " var; do [ "$var" == . ] && break; done)'
$ scratch
:-> a
:-> b
:-> c
:-> .

Ctrl但是,您也可以通过使用+发送 EOF 来退出D

答案2

用于read逐行读取输入。您可以指定提示。以下代码片段读取行并忽略其内容,直到该行包含单个点周围的可选空格,或者直到您在空白行上按Ctrl+ 。D

scratch () {
  local line
  while [[ "$line" != "." ]] && read -r -e -p "scratch> " line; do :; done
}

相关内容