如何在bash命令行中输入多行命令

如何在bash命令行中输入多行命令

我正在对脚本进行故障排除,我想手动输入每一行,逐行查找错误。

我的脚本有一个 if 语句:

if [ -d dir1 ]; then
    rm -rf dir1
fi

所以我尝试输入一行命令

$ if [ -d dir1 ]; then rm -rf dir1 fi
> 

我尝试了 Ctrl-D 但收到消息:bash: 语法错误:意外的文件结尾

那么如何在命令行中输入这个if语句呢?

答案1

简短回答:后面需要一个分号rm -rf dir1

查看实际效果:if完全按照脚本中显示的方式输入块:

$ if [ -d dir1 ]; then
>     rm -rf dir1
> fi

运行后,使用向上箭头回调最后一个命令,它将if在一行上显示整个块:

$ if [ -d dir1 ]; then rm -rf dir1; fi

shell 需要某种方式来解释 if 块内命令之间的中断。它不能简单地将其视为一次执行的单个命令,因此分号充当这些中断。

答案2

除了约翰的答案是完全正确的,但最终仍然会导致您输入(非常长的)单行命令,还有一种输入多行命令的实际方法:

$ if [ -d dir1 ]; then
>         rm -rf dir1
> fi

那是……只需输入。输入后,shell 将发现该命令尚未完成并提供“继续提示”。

但是如果命令实际上已经完成,或者您不想依赖它?也有可能。

它被称为 VLNEXT 并且通常设置为^V,但如果你想使真的当然,检查stty -a输出并在 cchars 组中查找lnext(在 BSD 上;GNU stty 是一个相当未排序的输出,但对我来说它位于第三行)。

作为一个额外的复杂性,在煮熟的模式下,按 Enter 键提交^M(ASCII 0x0D),但我们实际上需要 ASCII 0x0A,因此^J您必须按 VLNEXT。

然后,我们可以输入if [ -d dir1 ]; then^V^Jrm -rf dir1^V^JfiEnter,它会将其作为一个大命令运行。在 GNU 中看起来像这样……

$ if [ -d dir1 ]; then
rm -rf dir1
fi

...当按下查看历史记录时,您会看到它实际上保存了带有分号的单行表格。

其他 shell 的呈现方式可能有所不同 - 例如,输入时会这样显示...

$ if [ -d dir1 ]; then^Jrm -rf dir1^Jfi

……如果你按下,你会看到它像历史上那样保存它。如果您按几次,您会注意到这些^J被视为单个字符,因为它实际上是一个控制字符,而不是两个字符^(插入符号)和J

因此,GNU bash 将具有更好的输入,但会在内部对其进行转换,而 mksh 具有单行输入(和命令行编辑),但将其完全按照键入的方式保留在历史记录中。

输入时看起来像多行 bash...

% if [ -d dir1 ]; then
rm -rf dir1
fi

…这也存储在历史记录中(就像在 mksh 中一样,但 zsh 具有多行输入编辑功能,因此可以在行中上下移动光标,从而将其扩展^J为实际的换行符;不过,这有缺点,按下^U不再杀死整个输入,而只杀死其中的一个子行)。

表现得像 1999 年的因为它输入^J一行(就像 mksh 一样),但将每一行单独保存到历史记录中,因此您得到的只是最后一行fi,这可能非常没有帮助。

现代(Debian 稳定/靶心)这里的行为类似于 mksh。

现代 AT&T ksh93“u+m” 甚至更奇怪:输入时,它的行为就像 pdksh/mksh 谱系中的表亲一样,但是当按下它时(仅)获取第一的命令行(而不是像 pdksh 那样的最后一行),这可能也不是很有帮助。

是……奇怪。因为^V^J它显示^M内联(但在其他方面的行为类似于 mksh,当然,因为它不是 POSIX 兼容的 shell,所以该if命令将因语法错误而失败),而对于两者^V^M^VEnter,它的行为就像只是按下了 Enter 一样。

> if [ -d dir1 ]; then^Mrm -rf dir1^Mfi
if: Expression Syntax.
rm: Command not found.

最后,原来的……

% if [ -d dir1 ]; then^Jrm -rf dir1^Jfi
if: Expression Syntax.

……没有什么惊喜。它没有交互式方式来检索历史记录,并且发出命令history来显示保存的行不会给出任何输出(即使是简单的ls),所以我相信它需要启用一些设置或其他东西(我从未使用过C 壳)。

全面披露:我是 mksh 开发人员。

答案3

这是特定于 shell 的,但有一种方法可以将当前正在编辑的行放入默认编辑器中,您可以在其中编辑它,然后保存并退出。完成此操作后,它将相应地更新命令行上的命令,然后您只需按 Enter 即可运行该命令。

巴什你想要的击键是CtrlxCtrle(那是2个键和弦,一个在下一个之后输入)

确保您的EDITOR环境变量设置为您首选的编辑器。

相关内容