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 中以任何方式执行命令有什么用?

对 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)
help即使对于{关键字,内置函数也很有用。来自help -m {:
Run Code Online (Sandbox Code Playgroud)NAME { ... } - Group commands as a unit. SYNOPSIS { COMMANDS ; }
因此,;每个命令后的分号 ( ) 是必需的。