标签: subshell

为子shell设置环境变量

我知道我可以使用这样的环境变量运行命令:

FOO=bar mycommand
Run Code Online (Sandbox Code Playgroud)

我知道我可以在这样的子 shell 中运行命令:

(firstcommand && secondcommand)
Run Code Online (Sandbox Code Playgroud)

但是我可以以某种方式将这两者结合起来吗?

FOO=bar (firstcommand && secondcommand)
Run Code Online (Sandbox Code Playgroud)

给出:

sh: syntax error: unexpected "("
Run Code Online (Sandbox Code Playgroud)

至少在busybox shell(灰烬)中。

编辑: Kusalananda 建议FOO=bar sh -c 'first && second'这确实是一个解决方案。但是,我也对替代答案感兴趣,因为我喜欢 subshel​​l 语法,因为它不需要摆弄转义引号。

environment-variables ash subshell

15
推荐指数
1
解决办法
2万
查看次数

子壳和子壳是一样的吗

有这两个名称:subshel​​lchild-shell

是的,子进程将通过以下任一方式启动:

sh -c 'echo "Hello"'
( echo "hello" )
echo "$(echo "hello")
echo "hello" | cat
Run Code Online (Sandbox Code Playgroud)

是否全部相同并共享相同的名称?所有共享相同的属性吗?


POSIX有这个定义

一个shell执行环境包括....

但是上面链接的最后一段是这样的:

子shell 环境应创建为shell 环境的副本,除了未被忽略的信号陷阱应设置为默认操作。

特别是:

命令替换、用括号分组的命令和异步列表应在子 shell 环境中执行。另外,多命令管道的每个命令都在一个子shell环境中;....

sh -c 'echo "Hello"'不包括有,应该是可以称为子shell?

shell bash process posix subshell

14
推荐指数
1
解决办法
4161
查看次数

子shell和进程替换之间的区别

在 bash 中,我想将当前工作目录分配给一个变量。使用子shell,我可以做到这一点。

var=$(pwd)

echo $var
/home/user.name
Run Code Online (Sandbox Code Playgroud)

如果我像这样使用进程替换:

var=<(pwd)

echo $var
/dev/fd/63
Run Code Online (Sandbox Code Playgroud)

我知道进程替换主要在程序不接受 STDIN 时使用。我不清楚进程替换究竟做了什么以及为什么它分配/dev/fd/63var.

process process-substitution subshell

14
推荐指数
1
解决办法
2993
查看次数

子shell的Bash语法高亮

考虑到大量与 Bash 中的子 shell 相关的问题(“为什么我的变量在这个管道while read循环中没有增加?”),我只是认为参考一些编辑器或服务代码会非常好将在子 shell 中执行的格式与在父 shell 中执行的代码格式不同。它可能作为一种教育设备很有用(查看code | codecode < <(code)立即之间的区别)。这存在吗?

如果有人为 jEdit 或 VIm 实现它,则加分。

显然,这并不一定是完美的(没有语法高亮,在我的经验),但我怀疑的东西喜欢(foo=bar; echo $foo;)command | while read ...不应该一开始太困难了。

bash syntax-highlighting subshell

13
推荐指数
1
解决办法
1479
查看次数

如何使子shell中的变量在父shell中可用

我编写了一个快速而肮脏的脚本来计时来自 Web 服务的一些报告:

BASE_URL='http://example.com/json/webservice/'
FIRST=1
FINAL=10000

for report_code in $(seq 1 $FINAL); do
  (time -p response=$(curl --write-out %{http_code} --silent -O ${BASE_URL}/${report_code}) ) 2> ${report_code}.time

  echo $response  # <------- this is out of scope!  How do I fix that?
  if [[ $response = '404' ]]; then
    echo "Deleting report # ${report_code}!"
    rm ${report_code}
  else
    echo "${report_code} seems to be good!"
  fi
done
Run Code Online (Sandbox Code Playgroud)

我需要将time命令包装在一个子 shell 中,以便我可以重定向它的输出,但这使得$response父 shell的值不可用。我该如何解决这个问题?

shell bash io-redirection subshell

13
推荐指数
1
解决办法
8968
查看次数

在执行之前展开子shell?

我经常使用子外壳运行命令,有时希望在运行某些东西之前扩展子外壳。这样我可以验证我在做什么,并可能编辑即将发生的事情。

例如,如何在运行之前扩展以下命令行,以便我可以编辑子shell的结果?

例如

$ find -name "test.txt" 
/tmp/test.txt

$ mv $(!!) /tmp/new.txt
Run Code Online (Sandbox Code Playgroud)

我希望运行命令之前看到扩展的子shell ,如下所示:

$ mv /tmp/test.txt /tmp/new.txt
Run Code Online (Sandbox Code Playgroud)

有没有办法做到这一点?

shell bash command-history subshell

12
推荐指数
1
解决办法
1767
查看次数

为什么大括号命令组在 POSIX Shell 语法中的左大括号后需要空格?

TL;DR:为什么 POSIX 括号组在{保留字后需要空格,而子外壳在保留字后不需要(

POSIX shell 语法定义花括号组和子shell如下

brace_group      : Lbrace compound_list Rbrace

subshell         : '(' compound_list ')'
Run Code Online (Sandbox Code Playgroud)

现在,如果我们从字面上看,空格很重要。这意味着必须有空间描述开始和结束括号和括号,如

{ echo hello world; }

( echo hello world )
Run Code Online (Sandbox Code Playgroud)

这也符合复合命令定义

这些复合命令中的每一个在开头都有一个保留字或控制运算符,并在末尾有一个相应的终止符保留字或运算符。

然而,没有意义的是为什么(list)并且( list )工作得很好((不需要后面的空格),但是大括号扩展必须有一个前导空格,即{echo hello;}不起作用。

当然,保留字被视为 shell 字是有意义的,之后需要一个空格来与字段拆分的概念保持一致,但是定义本身并没有提到空格。此外,如果{(都被复合命令的 POSIX 定义视为保留字,为什么在这些保留字之后的空格字符方面对它们的处理方式不同?现在,ksh(1)手册确实说明:

作为字符序列的单词由不带引号的空白字符(空格、制表符和换行符)或元字符(<、>、|、;、&、(和))分隔

换句话说,它是有道理的ksh的将认识到(作为字符,其中第一字将是一个命令或变量赋值。POSIX,但是似乎没有提到(作为元字符。就 POSIX 语法而言,我发现的唯一可能的解释是它{被认为是一个“标记”,而 as(没有被列为一个。

/* These are reserved words, not …
Run Code Online (Sandbox Code Playgroud)

shell posix subshell syntax

12
推荐指数
2
解决办法
747
查看次数

在子shell中设置-e

我认为set -e对子外壳和顶级外壳有相同的影响。显然,事实并非如此。这个:

(
  set -e
  false 
  true
) || echo false1


bash -ec '
  set -e
  false 
  true
' || echo false2


bash <<EOF || echo false3
  set -e
  false 
  true
EOF

bash <<EOF || echo false4
  false 
  true
EOF

bash <<EOF || echo false5
  false  &&
  true
EOF
Run Code Online (Sandbox Code Playgroud)

印刷

false2
false3
false5
Run Code Online (Sandbox Code Playgroud)

这是在哪里记录的?我可以让子外壳程序在错误时终止,而不用&&(或|| exit $?在每个命令之后不执行)连接所有命令吗?

编辑:

我的特定用例是这样的:

set -e
  # ...
status=0
( false; true ) || status=$?
report_code $status
return $status
Run Code Online (Sandbox Code Playgroud)

子shell的内容是我的实际代码。这样做的问题是它总是将状态设置为 …

shell subshell

11
推荐指数
1
解决办法
3412
查看次数

bash 与 zsh 中子 shell 和 &amp;&amp; 的不同行为

我对在子 shell 中运行命令的理解是,当前 shell 被分叉,然后子 shell 进一步执行fork所需exec的命令。

在 bash 和 zsh 中运行以下命令时,我看到奇怪的行为:
$ ( sleep 5 && sleep 6 )

在bash中运行时:

$ echo $$
6410
$ ( sleep 5 && sleep 6 )
Run Code Online (Sandbox Code Playgroud)

ps给出以下内容:
CMD:睡眠 5
PID:6590
PPID:6589

然后:
CMD:睡眠 6
PID:6616
PPID:6589

这对我来说都是有道理的。sleep 5并且sleep 6两者具有相同的父级(大概是子shell)。

但是,在zsh中,我得到以下信息:

$ echo $$
1987
$ ( sleep 5 && sleep 6 )
Run Code Online (Sandbox Code Playgroud)

ps给出以下内容:
CMD:睡眠 5
PID: …

bash zsh subshell

10
推荐指数
1
解决办法
1595
查看次数

脚本可以作为子 shell 运行吗?

脚本通常以 shebang 开头,例如#!/usr/bin/env bash,它指定要用于执行的 shell。shebang 不存在时的执行行为似乎取决于调用 shell。无论哪种方式,脚本都是从“新”shell 运行的,该 shell 不知道调用 shell 中定义的变量和函数。

或者,也可以将脚本source放入 shell 中,根据我的理解,这相当于将脚本内容复制粘贴到当前 shell 中。如果脚本中定义了任何函数或变量,那么它们在“执行”后将保留在调用 shell 中,这可能是不可取的。

这两个选项之间有什么关系吗?是否可以将脚本作为调用 shell 的子 shell 来执行,这样我们就可以访问调用 shell 中定义的所有内容,但不会修改它(除非可能使用export这样的命令)?

写作(source myscript.sh)似乎就是我所追求的;这是正确的做法吗?是否有一个等效的 shebang 可以通过调用来产生相同的行为./myscript.sh

scripting shell-script subshell

10
推荐指数
1
解决办法
1375
查看次数