有没有我运行时创建一个子shell`SH -c"指挥QUOT;`,这些新的外壳或无? [英] Is there a subshell created when I run `sh -c "command"`, a new shell or none of these?

查看:124
本文介绍了有没有我运行时创建一个子shell`SH -c"指挥QUOT;`,这些新的外壳或无?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在bash中,当我运行下面的命令:

  SH -c的命令 

有没有创建子shell,然后在命令执行?

我的猜测是,该命令将在当前shell中运行,但我不知道。这种猜测来自于我使用下面的命令已经测试过的事实:

 回声$ BASHPID,$ BASH_SUBSHELL

 上海-c回声$ BASHPID,$ BASH_SUBSHELL

和的结果是相同的。但是,这可能是一个有点误导,因为有人告诉我,因为执行该命令之前,变量可以被取代。这是事实吗?


解决方案

我觉得用实例有可能了解情况结果
(在我的情况 SH 是一个符号链接 /斌/破折号)。结果
我做了这个测试 SH

 回声$$; SH -c'回声$$; SH -c''回声$$
16102
7569
7570

三种不同的 PID ,三种不同的。 (如果有不同的的,没有一个的子shell 的重生)。


BASH

以类似的方式

 回声$$ $ BASHPID,$ BASH_SUBSHELL;庆典-c'回声$$ $ $ BASHPID BASH_SUBSHELL;庆典-c''回声$$ $ $ BASHPID BASH_SUBSHELL
16102 16102 0
10337 10337 0
10338 10338 0

三种不同的 $ BASHPID 无异 $ BASH_SUBSHELL (见下文注意,之间的差异$$ $ BASHPID )。结果
如果我们是在一个的子shell 的不需要重新初始化,那么 $ $ BASHPID 应该是不同的。结果
以同样的方式 $ BASH_SUBSHELL 没有增加,它始终是 0
所以2线索再次说,没有新的子shell 的产卵,我们只有新的


男人庆典(4.2.45(1) - 释放)我汇报一下一些相关部分的时的子shell是催生


  1. 管道中的每个命令作为一个单独的进程中执行
    (即在子shell 的)。


  2. 如果一个命令是由控制操作符的&安培; 后,shell将执行该
    命令在子shell后台。 shell不会等待
    命令来完成,并返回状态是0。

    由分开的命令;是顺序执行的; shell等待每个
    命令依次结束。返回状态是最后的退出状态
    命令执行。
                                        ...


  3. 列表中的列表在子shell 的环境中执行搜索
     {名单; }列表只是在当前shell环境中执行。


  4. A 协进程是在协处理器保留字pceded shell命令$ P $。一个协在异步执行子shell ...


  5. $ 扩展到 shell的进程ID 的。在()子shell 的,它扩展到
    当前的的进程ID,而不是的子shell


备注


  • BASHPID 扩展为当前bash进程的进程ID。这不同于 $
    在某些情况下,例如,不需要的bash是子shell
    重新初始化。

  • BASH_SUBSHELL 由一个每一个子shell子shell或环境的催生时间递增。的初始值是0


  • 有关使用单引号之间的差异一个双引号 you可以看到这个问题。让我们只记得,如果你写双引号中的命令中的变量将通过从原来的的,如果<参数扩展进行评估EM> extquote 的启用,因为它是在默认情况下从禁用了javascript (CFR。 4.3.2 shopt内建的Bash的参考手册)


      

    * extquote *
      如果设置,$字符串和$字符串引用是内双引号括起来$ {}参数进行扩展。此选项默认是启用的。



有关更多参考资料可能对你有用例如

In bash, when I run the following command:

sh -c "command"

is there created a subshell and then the command is executed?

My guess is that the command will run in the current shell, but I'm not sure. This guess come from the fact that I already tested using the following commands:

echo $BASHPID, $BASH_SUBSHELL

and

sh -c "echo $BASHPID, $BASH_SUBSHELL"

and the results are the same. But this could be a little misleading as someone told me because the variables may be substituted before the command is executed. Is this the truth?

解决方案

I think that with examples it's possible to understand the situation
(in my case sh is a symbolic link to /bin/dash).
I did this tests for sh:

echo $$ ; sh -c 'echo $$ ; sh -c '"'"'echo $$'"'"' '
16102
7569
7570

Three different PID, three different shell. (If there are different shells, there is not a subshell spawn).


In a similar way for BASH

echo $$ $BASHPID, $BASH_SUBSHELL ; bash -c 'echo $$  $BASHPID $BASH_SUBSHELL  ; bash -c '"'"'echo  $$ $BASHPID $BASH_SUBSHELL '"'"' '
16102 16102, 0
10337 10337 0
10338 10338 0

Three different $BASHPID no different $BASH_SUBSHELL (see note below for differences between $$ and $BASHPID).
If we were in a subshell that do not require to be reinitialized, then $$ and $BASHPID should be different.
In the same way $BASH_SUBSHELL is not incremented, it is always 0. So 2 clues to say again that no new subshell are spawned, we have only new shells.


From man bash (4.2.45(1)-release) I report some pertinent parts about when a subshell is spawned:

  1. Each command in a pipeline is executed as a separate process (i.e., in a subshell).

  2. If a command is terminated by the control operator &, the shell executes the command in the background in a subshell. The shell does not wait for the command to finish, and the return status is 0.

    Commands separated by a ; are executed sequentially; the shell waits for each command to terminate in turn. The return status is the exit status of the last command executed. ...

  3. ( list ) list is executed in a subshell environment
    { list; } list is simply executed in the current shell environment.

  4. A coprocess is a shell command preceded by the coproc reserved word. A coprocess is executed asynchronously in a subshell...

  5. $ Expands to the process ID of the shell. In a () subshell, it expands to the process ID of the current shell, not the subshell.

Notes:

  • BASHPID Expands to the process ID of the current bash process. This differs from $$ under certain circumstances, such as subshells that do not require bash to be re-initialized.
  • BASH_SUBSHELL Incremented by one each time a subshell or subshell environment is spawned. The initial value is 0.

  • For the differences between the use of single quote '' an double quote "" you can see this question. Let we remember only that if you write the commands within double quote"" the variables will be evaluated via parameter expansion from the original shell, if extquote is enabled as it is by default from shopt.(cfr. 4.3.2 The shopt builtin in the Bash Reference Manual)

    *extquote* If set, $'string' and $"string" quoting is performed within ${parameter} expansions enclosed in double quotes. This option is enabled by default.

For further references you may find useful e.g.

这篇关于有没有我运行时创建一个子shell`SH -c&QUOT;指挥QUOT;`,这些新的外壳或无?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆