对我来说,有些不合理的是终端不像其他文本区域那样工作,比如我们在文本编辑器或浏览器上书写时。复制和粘贴、选择文本等功能在终端中的工作方式不同。
是否可以运行一个像普通文本编辑器一样工作的终端,当我们按下某些键时它只会运行我们编写的命令?
编辑
为了更清楚地表达我的意思,我问的正是@Ghos3t 指出在评论中:
我认为每个人都没有理解 OP 所问的问题的含义,他不想要像 nano 这样的终端文本编辑器,他谈论的是我们输入终端命令的文本提示符,以及为什么它不遵循像任何普通文本框那样的约定,比如可以选择按 Ctrl/Cmd + A 选择整行并按退格键删除它,而不必一次退格一个字符,或者普通的复制和粘贴命令在某些终端中不起作用等等。为什么终端文本提示符不能像 VSCode 命令面板那样工作。
我们能否拥有一个严格遵循与文本编辑器相同模式的终端?为什么终端遵循的模式与文本区域不同?
答案1
通常情况下,Bash 将处于emacs
模式。如果是这种情况(并且如来自 @frabjous 的评论),您可以按Ctrl+ ,x然后按Ctrl+e进入“文本编辑器模式”。这可以通过以下方式完成:空白命令行,或者通过编辑现有命令已经输入了。
现在您可以在文本编辑器中输入所有命令,当您退出时,每一行都将作为一条命令执行 - 就像它是一个 Bash 脚本一样。
编辑器默认为vim
。要设置另一个编辑器(在本例中为nano
),请设置环境变量EDITOR
,方法是将以下内容添加到您的 中~/.bashrc
:
export EDITOR=nano
重要警告
另一篇帖子Unix 和 Linux用户 marlar 对此功能发出了重要警告:
使用此功能时请务必小心。如果您取消编辑,原始命令行将立即执行。因此,如果您正在编辑
rm -rf /
并调用编辑器,并意识到自己遇到了危险并因此取消编辑,您的 rootfs 将被删除,而不会进一步询问。
如果你使用空白命令开始,这不是问题,但如果你使用可能具有破坏性的现有命令开始,总是退出编辑器之前清除文件并保存。
有一个可能的解决方法在这个超级用户的回答中。还请注意,这主要是 Bash 问题。Zsh 和 Fish 只会将命令粘贴到提示符中,而不会执行它。
高级用户提示
你可能会发现自己处于这样一种情况(就像我一样),即键绑定Ctrl+x已被某个应用程序使用,并在到达 Bash 之前捕获到它(这可以是您的终端仿真器、多路复用器等等tmux
)。
在这种情况下,您可以将Ctrl+重新绑定x到另一个组合键。这可以通过在您的中添加此行来完成~/.bashrc
:
bind '"\C-f":"\C-x"'
在此示例中,按下+时,会向 Bash 发送一个Ctrl+序列。因此,现在您已将硬编码键绑定+重新映射到+xCtrlfCtrlxCtrlf (它实际上是在 Bash 使用的 Readline 库中定义的)。
答案2
因为终端实际上是终端仿真器。它们模拟的是基于线……因为它们来自非常遥远的过去。最初的终端并不比打字机更智能。
如今,我们的屏幕可以随意重绘。在文本编辑器中,您可以单击任意位置来将插入光标设置在您想要的任何位置,但在以前,没有屏幕。只有打印机和键盘。最终,您可以删除输入的最后一个字符,或删除整行,但仅此而已。
随着时间的推移,终端(硬件终端)变得越来越强大和智能,最终神奇的 VT100 应运而生。我们今天使用的终端仿真器或多或少模拟了 VT100,并添加了一些功能(例如,当前的终端仿真器可以正确处理国家字符:欧洲语言及其奇怪的符号(ç Æ、ñ、Å...)、希腊语、希伯来语、亚洲语言,实际上是大多数 Unicode 符号)
他们的命令集在图形用户界面出现之前就存在了。在终端中,Control-C 被终端驱动程序捕获并映射到一个信号,该信号会友好地要求当前进程终止。这已成为历史。还请注意,在终端中,您实际上并不是在编辑文本(不考虑您可以在全屏模式下运行编辑器的事实),您键入一个字母,该字母被发送到计算机,计算机发回该字母,然后该字母被打印在屏幕上。当您按下回车键时,远程计算机将执行命令,您只会收到输出。
为什么我们没有发明可以像在任何其他文本窗口中一样进行编辑的终端?因为这没有意义。终端是顺序的:从逻辑上讲,我们按顺序输入命令并得到答案。还因为它的工作方式。每个字符都会被发送,当(如果)它返回时,它会被打印在屏幕上。鼠标光标、移动插入光标如何适应这个模型?
答案3
我有一个建议,它并不完全按照你的要求去做,而是以更灵活的方式做类似的事情。
您可以创建自己的脚本,启动一个文本编辑器,您可以在其中输入“脚本”(仅命令),当您退出并保存时,命令就会被执行。
首先,创建以下脚本:
#!/bin/bash
filepath="/dev/shm"
# Give a unique filename
date=$(date '+%Y%m%d-%H%M%S')
# Open your favorite editor ('nano' by default)
nano "$filepath/$date"
# Only execute if file is acatually written
if [[ -f "$filepath/$date" ]]
then
# Insert shebang for interpreter ('/bin/bash' by default)
sed -i '1i#!/bin/bash\' "$filepath/$date"
# Make file executable
chmod +x "$filepath/$date"
# Run the script you just made
"$filepath/$date"
# Delete the script again (comment out if you want to preserve the history)
# rm "$filepath/$date"
fi
现在将此脚本另存为run-commands
,将其放在您的某个位置PATH
并使其可执行(chmod +x ./run-commands
)。
此外,您可以编辑.bash_aliases
并添加以下内容:
alias rc='run-commands'
bind -x '"\C-r":run-commands'
现在,它是这样工作的:
- 如果您键入
rc
或按Ctrl+ R,您现在将打开一个文本编辑器(nano
默认)。 - 您可以在这里逐行输入命令 - 就像在任何其他 shell 脚本中一样。
- 当您退出编辑器(Ctrl+ X,默认情况Y下Enter)时,脚本将被创建、可执行并运行!
- 创建的命令(脚本)位于 中
/dev/shm
,这是 Ubuntu 提供的默认 ramdisk。重启后会清除该命令(这对我来说很有意义)。
与您的问题相比,这有一些优点和缺点。
优点:
- 与用更难维护的东西替换整个外壳相比,该解决方案更容易实现,也更灵活。
- 您不会丢失任何现有的功能,而只会在需要时添加其他功能。
- 您可以自由自定义默认要使用的编辑器(
nano
默认)和 shell(/bin/bash
默认)。 - 该脚本的功能可以轻松扩展,包括历史功能、编辑以前的命令、支持更多解释器等。(如果有一天我有时间,我可能会看看这个。)
缺点:
- 您必须激活组合键(或运行
rc
)才能启动该脚本调用的特殊“脚本模式”。 - 您必须先使用文本编辑器的常用组合键保存脚本,然后才能运行命令。