这个组{ echo hello; echo world; }
完全按照它在bash shell文件中所说的完成。它输出(od -xa
)
0000000 6568 6c6c 0a6f 6f77 6c72 0a64
h e l l o nl w o r l d nl
0000014
如果我在.bashrc
中定义了以下内容:
show_command_in_title_bar()
{
case "${BASH_COMMAND}" in
*\033]O*|*\\e]0*)
true;;
my_prompt_command)
true;;
*)
printf "\e]0;%s\a" "${BASH_COMMAND}";;
esac
}
trap show_command_in_title_bar DEBUG
...我运行以下重定向:
{ echo hello; echo world; } > a
然后文件的内容是:
0000000 5d1b 3b30 6365 6f68 6820 6c65 6f6c 6807
esc ] 0 ; e c h o sp h e l l o bel h
0000020 6c65 6f6c 1b0a 305d 653b 6863 206f 6f77
e l l o nl esc ] 0 ; e c h o sp w o
0000040 6c72 0764 6f77 6c72 0a64
r l d bel w o r l d nl
0000052
我不会远程了解发生了什么。使用| od -xa
管道同一组显示正确的结果。使用| tee a
写入文件也可以。
为什么互动式echo
会触发DEBUG
?
答案 0 :(得分:3)
默认情况下,DEBUG陷阱已禁用:
管道在子shell中运行,因此| tee a
实例禁用了陷阱。
但是,没有任何子shell的命令分组都不是这三个类别。因此,执行陷阱(并打印您询问的内容)符合正确的记录行为。
我的主要建议不是(ab)使用DEBUG陷阱来达到目的。
我的第二个建议是将用于人类消费的内容指向stderr,或者(甚至更好)/dev/tty
- 而不是stdout。因此,该行将成为:
printf '\e]0;%s\a' "${BASH_COMMAND}" >/dev/tty
或者,您可以预先打开指向.bashrc
中TTY的文件描述符。如果使用bash 4.1的自动文件描述符分配,那么函数定义后.bashrc
中的代码将变为:
# open a file descriptor on the TTY *once*, instead of doing it over and over
# the trailing "||:" prevents this from being an error if it fails
exec {tty_fd}>/dev/tty ||:
# when running the code in the trap, use that file descriptor
# similarly, the ||: means our DEBUG trap never returns false
trap '[[ $tty_fd ]] && show_command_in_title_bar >&$tty_fd ||:' DEBUG