如何在主 shell 中运行命令块?

sha*_*ant 8 command-line shell bash

我尝试在主 shell 内整体运行一系列命令,但我被教导的方式仅在子 shell 内有效:

 echo $BASHPID
18884
 (echo "hello $BASHPID";sleep 5;echo "hello again $BASHPID")
hello 22268
hello again 22268
Run Code Online (Sandbox Code Playgroud)

我也试过:

. (echo "hello $BASHPID";sleep 5;echo "hello again $BASHPID")
source (echo "hello $BASHPID";sleep 5;echo "hello again $BASHPID")
Run Code Online (Sandbox Code Playgroud)

使用 source 命令,因为我了解到它会强制脚本在主 shell 内运行。

我想,如果我将命令放在一个文件中并使用 source 命令运行它,它会起作用,但我想知道是否有超出脚本文件的方法。

Sté*_*las 12

取决于你的整体意思。

如果你只是想向 shell 发送几个命令,并确保 shell 在你输入它们之前不会开始运行它们,那么你可以这样做:

cmd1; cmd2
Run Code Online (Sandbox Code Playgroud)

或者

cmd1 Ctrl+VCtrl+Jcmd2

(或启用括号粘贴 ( bind 'set enable-bracketed-paste on') 并从支持括号粘贴的终端粘贴命令)。

或者:

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

将它们放在几条线上。

例如,如果您想将它们分组以便它们共享相同的标准输入或标准输出,您可以使用:

{ cmd1; cmd2; } < in > out
Run Code Online (Sandbox Code Playgroud)

或者

eval 'cmd1; cmd2' < in > out
Run Code Online (Sandbox Code Playgroud)

如果您希望它们使用自己的变量和选项范围运行,因为bash没有等效的zsh匿名函数,您需要定义一个临时函数:

f() { local var; var=foo; bar;}; f
Run Code Online (Sandbox Code Playgroud)


Oli*_*lac 10

代替( something ),something在子shell中启动,使用{ something ; }something在当前shell中启动

之后需要空格{,并且;在 之前也应该有一个(或换行符)}

前任:

$ { echo "hello $BASHPID";sleep 5;echo "hello again $BASHPID" ; }
hello 3536
hello again 3536
Run Code Online (Sandbox Code Playgroud)

但是请注意,如果您启动一些复杂的命令(或管道命令),无论如何这些命令大部分时间都将位于子 shell 中。

获取当前 shell 的 pid 的“便携式”方法是$$.

所以我会把你的测试写成:

{ echo "hello $$"; sleep 5 ; echo "hello again $$" ; }
Run Code Online (Sandbox Code Playgroud)

(无论如何,睡眠在这里并不是真的有用)

  • 只有在打开 '{' 之后才需要空格,并且在关闭 ';}' 之前需要一个分号,只有当您的代码块在一行中时才需要!这意味着换行会使分号无用 (2认同)