标签: subshell

如何为子流程设置列和行

我有一个脚本,它运行一系列编号为 001,002,003,004...等的脚本,现在一直到 041,将来会更多 - 这些脚本本身使用一些光标控件来打印进度条和其他状态信息并获取终端的宽度和高度分别为tput colstput lines

在不重写子脚本的情况下,我想在底部保留一行用于外部脚本的总体状态信息。我很好奇是否有办法设置 tput 对行和列的回复。

一定有办法,因为 tmux 实现了它。我认为可能存在环境变量,但我可以看到 tmux 在运行 env 时所做的唯一更改是将 $TERM 设置为屏幕。

任何帮助将不胜感激

scripting gnu-screen tmux shell-script subshell

5
推荐指数
1
解决办法
3498
查看次数

Bash 和子外壳

从我从在线文档中收集的信息来看,以下内容应该为嵌入的命令部分生成一个子shell {}

$ bash -c '{ sleep 10; echo "Sleeping process", $$; }  & echo $$; '
11237
 Sleeping process, 11237
Run Code Online (Sandbox Code Playgroud)

但是,正如您所看到的,在这两种情况下,进程 ID 是相同的。我错过了什么?感谢您的指点。

shell bash subshell

5
推荐指数
2
解决办法
1461
查看次数

在`fork`、子进程和“子shell”上

这篇文章基本上是对我之前的一个问题的跟进。

从这个问题的答案中,我意识到不仅我不太了解“子外壳”的整个概念,而且更一般地说,我不了解fork-ing 和子进程之间的关系。

我曾经认为,当进程X执行 a 时fork,会创建一个进程Y,其父进程是X,但根据该问题的答案,

[a] subshel​​l 不是一个全新的进程,而是现有进程的一个分支。

这里的含义是“分叉”不是(或不会导致)“一个全新的过程”。

我现在很迷茫,实在是太迷糊了,无法提出一个连贯的问题来直接打消我的迷茫。

然而,我可以提出一个可能间接导致启蒙的问题。

因为,根据zshall(1),$ZDOTDIR/.zshenv每当一个新的实例zsh启动时就会被获取,那么任何$ZDOTDIR/.zshenv导致创建“一个全新的 [zsh] 进程”的命令都会导致无限回归。另一方面,在$ZDOTDIR/.zshenv文件中包含以下任一行不会导致无限回归:

echo $(date; printenv; echo $$) > /dev/null    #1
(date; printenv; echo $$)                      #2
Run Code Online (Sandbox Code Playgroud)

我发现通过上述机制引起无限回归的唯一方法是在文件中包含如下所示的行1$ZDOTDIR/.zshenv

$SHELL -c 'date; printenv; echo $$'            #3
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  1. 由于这种行为差异#1#2上面标记的命令和标记为#3帐户的命令之间有什么区别?

  2. 如果获得创建的壳#1#2被称为“子shell”,那些是什么样所产生的一个 …

process zsh fork subshell

5
推荐指数
1
解决办法
2465
查看次数

shell 中导出变量的范围

假设我有一个脚本,我在其中导出了一个变量,如下所示:

#!/bin/bash
foo(){
    eval export one=1
}
foo1(){
    eval export two=2
}
(foo)
foo1
echo "one=$one"
echo "two=$two"
Run Code Online (Sandbox Code Playgroud)

但是我得到了以下输出:

root@centos1:~>/tmp/test.sh
one=
two=2 
Run Code Online (Sandbox Code Playgroud)

什么可能是我无法看到的价值$one和可以看到的原因$two

shell subshell variable

5
推荐指数
1
解决办法
6291
查看次数

如何在后台放置子shell和相关命令?

在子 shell 中运行序列命令,如下所示:

(git pull;git rebase develop)&>/dev/null 
Run Code Online (Sandbox Code Playgroud)

我认为这会将子 shell 及其创建的所有子进程置于后台,并将控制权返回给用户。

但实际上,终端挂了一段时间,似乎是在等待子shell中的命令完成。

任何人都可以解释为什么会发生这种情况,以及做这种工作的正确方法是什么。

shell-script background-process subshell

5
推荐指数
1
解决办法
564
查看次数

在 bash 中创建子shell的所有方法是什么?

到目前为止,我知道有两种主要方式:

  • 显式:将括号括在命令列表中

  • 隐式:管道中的每个命令

是否有更多的方式,无论是显式还是隐式,在 bash 中创建子shell?

bash subshell

5
推荐指数
1
解决办法
4417
查看次数

为什么 (...) 在后台运行时不会产生新的子进程?

运行命令后

{ sleep 5; } &  
Run Code Online (Sandbox Code Playgroud)

输出ps是(输出1)

 PID TTY           TIME CMD
  972 ttys000    0:00.27 -bash
 2556 ttys000    0:00.00 -bash
 2557 ttys000    0:00.00 sleep 5   
Run Code Online (Sandbox Code Playgroud)

而对于

( sleep 5 ) &    
Run Code Online (Sandbox Code Playgroud)

ps是(输出 2)

PID TTY           TIME CMD
 972 ttys000    0:00.28 -bash
2566 ttys000    0:00.00 sleep 5  
Run Code Online (Sandbox Code Playgroud)

()导致子shell环境,我希望在这种情况下为“输出1”,因为它会导致子进程分叉,而我希望{ sleep 5; } &在当前shell中执行时为“输出2” 。这可能看起来是一个愚蠢的问题,但我真的不明白这种行为。
我在这里缺少什么?

bash command subshell

5
推荐指数
1
解决办法
3783
查看次数

如何处理异步子shell退出

说我有这个:

set -e;

(
    docker stop notifier-server
    docker rm -f notifier-server
    exit 1  # explicitly exit with non-zero
) &

wait;

echo 'we are here now'
Run Code Online (Sandbox Code Playgroud)

即使子shell以非零值退出,我们是否总是会到达回声线?我认为是的,因为它是一个后端进程/子shell?

看待这个问题的正确方法是什么?

shell bash background-process subshell

5
推荐指数
1
解决办法
164
查看次数

作业控制真的应该在子 shell 和脚本中得到支持吗?

场地小

\n\n

我经常使用子 shell 来执行涉及更改Shell 执行环境的操作,以免影响主 shell。我经常从交互式 shell 中执行此操作,有时也从脚本中执行此操作。

\n\n

启用或禁用作业控制当然是这些操作之一,无论出于何种原因,当需要精细控制进程分组时,我一直在随意使用此功能。

\n\n

然而,作为 Bash 用户,我注意到这种自由在最新版本中得到了加强:直到 v4.3,作业控制才被允许并在交互式子 shell 中完全工作,但自 v4.4 以来就不再这样了。在那里,它仍然可以在交互式子 shell 中使用,但不能完全工作(见下文)。它在脚本内仍然可以很好地工作,但是,自 v5 以来,至少一个作业控制的特定用例(即 的细粒度处理Ctrl+C)已经更加严格,使其只能从脚本内的子 shell 内进行管理..!

\n\n

因此,我开始产生怀疑,因此花了一些时间对一些常见的 shell 进行了示例综合测试,所有这些测试都是在 Ubuntu 19.04 上使用其测试 shell 的库存(和发行版更新)版本执行的。

\n\n

一些背景

\n\n

我注意到bash, yash, mksh, 和zshdo Honorset -m在子 shell 中,而dashkshdo 则没有。ksh即使在测试结束时被拦住也很奇怪。

\n\n

TL; DR:接下来是我刚才所说的漫长的演示会议:

\n\n
$ bash -c \'echo start; (set -bm; …
Run Code Online (Sandbox Code Playgroud)

job-control shell-script subshell

5
推荐指数
0
解决办法
458
查看次数

为什么我必须在使用管道时将读取的命令放入子shell

该命令df .可以向我们显示我们在哪个设备上。例如,

me@ubuntu1804:~$ df .
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/sdb1       61664044 8510340  49991644  15% /home
Run Code Online (Sandbox Code Playgroud)

现在我想得到字符串/dev/sdb1

我这样试过,但没有用:df . | read a; read a b; echo "$a",这个命令给了我一个空的输出。但df . | (read a; read a b; echo "$a")会按预期工作。

我现在有点困惑。

我知道这(read a; read a b; echo "$a")是一个子shell,但我不知道为什么我必须在这里制作一个子shell。据我了解,x|y会将 的输出重定向xy. 为什么read a; read a b; echo $a不能获得输入但子外壳可以?

bash pipe subshell read

5
推荐指数
1
解决办法
467
查看次数