标签: subshell

键入命令后如何跟踪正在调用的系统调用?

这个问题与“当我们在 shell 上输入一个简单的命令时会发生什么?”的问题相关。我之前发过。(我认为分开发布会更好。但如果没有,请告诉我。)

我从上一个问题中了解到,shell 内置命令被特殊处理,正常的外部命令在子进程上执行。

这一次,我想跟踪系统调用,例如 fork、clone 或 execve,以监视键入命令后真正发生的情况。但是execve("bin/ls",,,) = 0当我这样执行时,我只能跟踪一个 execve 调用strace

strace -etrace=execve,clone ls
Run Code Online (Sandbox Code Playgroud)

这意味着,正如我猜的那样,我只能监视在创建子进程后调用的系统调用。

要监视与创建新进程相关的所有系统调用,我必须做什么? 在这种情况下,使用bash -clike调用命令strace -etrace=execve,clone bash -c '{ ls; }'会有所帮助吗?

shell process subshell

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

将 Subshel​​l 后台进程 pid 分配给变量

我目前正在子 shell 中启动后台进程,想知道如何将其 pid 编号分配给子 shell 范围之外的变量?
我尝试了许多不同的方法,但MYPID始终设置为0.

MYPID = 0;
({ sleep 2 & }; $MYPID=$!)
({ sleep 2 & }; echo $!) > $MYPID
Run Code Online (Sandbox Code Playgroud)

它返回值的唯一方法是:

$MYPID=$({ sleep 2 & }; echo $!)
Run Code Online (Sandbox Code Playgroud)

然而,这会丢弃后台进程指令,它只会在 2 秒后返回结果。

shell bash subshell variable

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

从 zsh 中的 subshel​​l 回显结果

在 zsh 中,以下 2 个命令的结果不同:

a=$(</etc/hosts) && echo $a
echo $(</etc/hosts)
Run Code Online (Sandbox Code Playgroud)

第一个逐行打印内容,而第二个将整个内容打印在一行中。

我猜是因为子shell将结果逐行返回给主echo进程,但我无法确认。

有人可以帮我清除吗?

zsh echo subshell

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

检查控制台应用程序是否真的退出

假设我已经启动了一个完成的控制台应用程序,然后 shell 提示再次出现。但是我怎么能确定它是真正的命令提示符呢?例如,如果应用程序是一个“键盘记录器”,当我尝试退出时它会启动一个假提示怎么办?

那么,我怎样才能检测到我实际上是在一个纯 shell(例如 bash)提示符下呢?

linux command-line shell bash subshell

5
推荐指数
3
解决办法
589
查看次数

是否有对 shell/Bash 中 stderr 上打印的任何内容的简单测试?

我想在 shell 脚本中调用一个命令以进行持续集成。退出状态 0 表示成功,否则失败。我正在编写一个包装脚本来运行多个命令,如果其中一个发生任何错误,则失败。

但是,其中一个命令(第 3 方软件)在失败时不符合“事实上的”退出状态 != 1。但是,如果出现故障,它会在 stderr 上打印其错误。

当前的包装器脚本,如果两者都可以正常工作,mycommand并且other-command由于-e切换而失败并退出状态 != 0 :

#!/bin/bash -ex
mycommand --some-argument /some/path/to/file
other-command --other-argument /some/other/file
Run Code Online (Sandbox Code Playgroud)

如何检查打印到 stderr 的任何内容(使主脚本失败)?这是我尝试过的:

  1. stderr 输出重定向到文件,检查文件内容。
    希望避免创建临时文件。
  2. 将 stderr 重定向到 subshel​​l stdin,例如:

    mycommand 2> >(if grep .; then echo NOK; else echo OK; fi)
    
    Run Code Online (Sandbox Code Playgroud)

    这似乎工作正常,但是,我无法控制此处的主 shell 退出,即exit 1不会退出主程序。我也不能控制子外壳之外的变量来传播它的结果。我真的必须创建一个命名管道吗?

  3. 这个答案一样设置额外的文件描述符。
    对我来说看起来不是很优雅,真的。

一些“要求”:

  • 它不应该在 stdout 上的常规输出上失败(也在那里输出)。
  • 我想在标准输出上保留其他有用的输出。
  • 我想保留当前在 stderr 上的任何输出打印(可能是 stdout,但不应该被隐藏)。

所以它应该表现得像一个包装器,只以不干净的状态退出,保留打印输出。

我只是希望有更优雅的东西来检查 stderr 中的任何内容。抨击是可以接受的。

bash file-descriptors exit subshell stderr

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

在子shell中处理替换以设置变量

我正在尝试远程运行脚本并使用其标准输出来填充变量。我这样做是为了避免临时文件。

这是我正在尝试的模式:

var=$(bash <(curl -fsSkL http://remote/file.sh))
echo "var=${var}"
Run Code Online (Sandbox Code Playgroud)

我正在测试这种模式而不curl使用cat

var=$(bash <(cat ./local/file.sh))
echo "var=${var}"
Run Code Online (Sandbox Code Playgroud)

就语法而言,这应该是相同的。 ./local/file.shcontains echo hello,所以我希望var包含 value hello,但唉,执行上述结果如下:

var=$(bash <(curl -fsSkL http://remote/file.sh))
echo "var=${var}"
Run Code Online (Sandbox Code Playgroud)

如何在不使用临时文件的情况下实现我的目标?

bash process-substitution subshell variable

4
推荐指数
1
解决办法
1531
查看次数

在bash中,如何在使用本地时检索子shell的退出代码

这个问题与其他问题很接近 -我可以从使用 $(command) 启动的子 shell 中获取退出代码吗?

但是,我发现没有解决方案可以让我在使用 local 和 eval 时从子 shell 获取退出代码,如本例所示...

test() {
> local WHY="$(eval "echo 'test'"; exit 3)"; echo $?
> }
test
0
Run Code Online (Sandbox Code Playgroud)

exit subshell exit-status

4
推荐指数
1
解决办法
552
查看次数

我可以确定是否通过命令替换调用了当前函数吗?

foo() {
  if [[ something ]]; then
    echo "The foo function was called directly."
  else
    echo "The foo function was invoked via command substitution."
  fi
}
Run Code Online (Sandbox Code Playgroud)

直接调用 foo:

foo

foo 函数被直接调用。

通过命令替换调用 foo:

a=$(foo) || exit 1
echo "${a}"
Run Code Online (Sandbox Code Playgroud)

foo 函数是通过命令替换调用的

有什么办法可以做到这一点吗?

bash command-substitution subshell

4
推荐指数
1
解决办法
57
查看次数

我需要让文件的每一行在其自己的子 shell 中运行

我有一个运行良好的脚本,但按系列运行。

我想让脚本从文本文件中获取每一行并在子 shell 中运行/生成该行,然后移至下一行,依此类推。

我需要子 shell 有两个原因:
首先,让作业并行运行而不是串行运行,从而使其运行速度更快。
其次,监视给定命令的输出并从远程系统返回退出代码。

有谁知道我怎样才能做到这一点?

作为一点背景知识,文本文件的每一行都是在远程系统上运行的 ssh 命令的集合,其中包含从用户输入和另一个输入文件收集的选项、函数,因此脚本生成的输出中的每一行都是一个独立的服务器的命令。

我通过动作调用脚本/bin/bash $temp_file

脚本示例类似于:

sshpass -p <PASSWORD> ssh -o StrictHostKeyChecking=no -p 22 USER@HOST.COM  'cat /etc/hostname  ;echo 'START';echo `date +%Y-%m-%d` ; echo <PASSWORD> |sudo -S yum update -y; cat /etc/hostname ;echo 'FINISH';echo `date +%Y-%m-%d` ;echo '';echo ''
Run Code Online (Sandbox Code Playgroud)

这只是一个示例,要运行的命令(例如yum update -y我在这里使用的 with echos 和 date)将被替换为单个命令或使用;$$来分隔它们。

我知道该行中有很多字符可能会导致问题。

shell-script subshell

4
推荐指数
2
解决办法
953
查看次数

子shell可以创建子进程吗?

因此,如果我输入如下命令,PID 4920子 shell 就会创建一个子进程 ( )。

linuxprobe@DESKTOP-TP0G72N:~$ (sleep 2;ps -f --forest;sleep 5)
UID          PID    PPID  C STIME TTY          TIME CMD
linuxpr+     513     512  0 Feb17 pts/0    00:00:00 -bash
linuxpr+    4920     513  0 01:35 pts/0    00:00:00  \_ -bash
linuxpr+    4922    4920  0 01:35 pts/0    00:00:00      \_ ps -f --forest
Run Code Online (Sandbox Code Playgroud)

如果我输入如下命令,似乎没有创建子进程

linuxprobe@DESKTOP-TP0G72N:~$ (ps -f --forest)
UID          PID    PPID  C STIME TTY          TIME CMD
linuxpr+     513     512  0 Feb17 pts/0    00:00:00 -bash
linuxpr+    5511     513  0 01:45 pts/0    00:00:00  \_ ps …
Run Code Online (Sandbox Code Playgroud)

linux subshell

4
推荐指数
1
解决办法
366
查看次数