Bash - 在当前 shell 中执行命令

use*_*885 8 command-line bash gnome-terminal

我正在阅读 O'Reilly 的书“Unix in a nutshell”,我在那里看到可以使用以下格式在当前 shell 中对命令进行分组和执行:

{ cmd1 ; cmd2 }
Run Code Online (Sandbox Code Playgroud)

我不明白这是怎么可能的,因为我知道对 exec 的调用会替换 shell 的数据,因此 shell 无法从 exec 系统调用中返回。所以我测试了命令,我不明白发生了什么。我输入了一个命令行,但我不确定该命令行属于什么。

它只是终端模拟器的命令行,从外壳中剥离出来吗?

另外,在当前 shell 中以任何方式执行命令有什么用?

在此处输入图片说明

Jo-*_*tad 10

这是因为你没有终止第二行:{ cmd1; cmd2; }是正确的。分号的意思是“命令结束”。


MvG*_*MvG 6

执行或不执行

对 exec 的调用会替换 shell 的数据,因此 shell 无法从 exec 系统调用中返回。

但并非每个命令都是要执行的程序的名称。所以通常不exec涉及呼叫。关键区别在于,与 相比( cmd1; cmd2; ),您不会获得另一个 shell 进程。或者更准确地说,shell 只会 fork 来执行子程序,而不是执行 shell 进程。

奇怪的提示

命令行属于什么。

正如其他答案所指出的那样,您的命令不完整。所以命令行属于 bash 本身,它正在等待你的组结束。

用途

另外,在当前 shell 中以任何方式执行命令有什么用?

...与子外壳分组相反

最突出的例子是在该子命令中设置变量。你这个:

foo=1; { foo=2; echo $foo; }; ( foo=3; echo $foo; ); echo $foo
Run Code Online (Sandbox Code Playgroud)

这将打印

2
3
2
Run Code Online (Sandbox Code Playgroud)

因此,尽管您foo=3在一个组内设置,但该组在子 shell 中执行,其设置不会传播到父级。

另一件值得考虑的事情是当前的工作目录。{ cd foo; make; }会将您留在目录中,foo( cd foo; make; )不会更改主 shell 的当前工作目录。

...与未分组的命令相反

如果您在外面有其他代码,则分组最有用,例如条件

test -f foo && { echo "Foo exists."; rm foo; }
Run Code Online (Sandbox Code Playgroud)

或重定向

{ echo "Content of $PWD:"; ls; } | gzip > dirlist.gz
Run Code Online (Sandbox Code Playgroud)


Rad*_*anu 5

help即使对于{关键字,内置函数也很有用。来自help -m {

NAME
    { ... } - Group commands as a unit.

SYNOPSIS
    { COMMANDS ; }
Run Code Online (Sandbox Code Playgroud)

因此,;每个命令后的分号 ( ) 是必需的。