如何在c中运行sh文件和导出变量

时间:2014-07-22 04:28:50

标签: linux bash shell export

我试图在c中读取导出的变量,但我不能,有两种情况。

A)

1)我有一个sh文件,如:

#!/bin/bash
timeout 3s ./program
export OUT=$?

2)然后我跑:. file.sh

3)当我用c读取变量:

getenv("OUT")是的,我读过它。

B)

    c:system("/bin/bash -c '. PathOfFile/file.sh'");

    中的
  1. getenv("OUT")。我无法访问OUT

  2. 我需要在c中运行sh文件并在c

    中读取var

    感谢

4 个答案:

答案 0 :(得分:1)

POSIX中的环境由新进程(由fork创建)继承,即子进程。但是当您更改子进程中的环境并且该进程结束时,没有任何东西可以保存环境或导致父进程获取除子进程的退出代码之外的任何信息。如果你想从子进程中保存一些东西,你必须使用某种形式的IPC来实现,从将它保存到文件中到使用套接字或memcached。

答案 1 :(得分:1)

如果' B' sh文件将在新进程中运行。

为了更清楚你可以做的是:

  1. 打开两个终端窗口。
  2. 在一个窗口中导出变量。
  3. 现在在另一个窗口中运行您的c程序。
  4. 您会发现您无法在第二个终端窗口中访问该变量。例如,A' A'您可以访问该变量,因为您从同一个终端窗口运行您的c程序(这使您的c程序成为终端会话的子进程)。所有子进程都从父进程继承环境变量。其他人提到您可以看到完成使用 pstree 命令处理树,您会发现 init 作为树的根目录。

    您可以做的另一个c文件包含:

    system(" / bin / bash -c' .PathOfFile / file.sh'");

    并在file.sh中首先导出变量,然后运行实际的c文件。

    另一种方法是使用IPC。

答案 2 :(得分:0)

您必须了解流程的概念。 system("/bin/bash -c '. PathOfFile/file.sh'");将为您创建一个运行file.sh的新进程,并在您的file.sh中声明OUT环境变量,换句话说,它存在于新进程的上下文中。但是,您只能在C代码(调用system函数)中获取环境变量,因为它是完全不同的进程上下文。当然,如果需要,您仍然可以使用IPC方法获取此环境变量。

答案 3 :(得分:0)

许多人会拒绝承认,但大多数 us 在发现环境变量之后都有完全相同的问题。今天,它似乎很明显"但那时候并不容易。因此,我会尽可能地尽可能简单地解释事情。

首先,正如其他人之前所说,你必须知道进程的概念。我不会详细介绍,但每次启动可执行程序时,都会创建一个新进程。在Unix / Linux世界中,进程是在严格的树层次结构中组织的。这就是所有过程都有一个独特的最终祖先叫initinit已在启动时启动了一些流程。反过来,这些进程已启动其他进程,依此类推,直到 shell ,您自己启动其他进程。所以:

  • 启动已编译的程序时,将创建一个新进程 (以你当前的shell作为父亲)。
  • 致电system时 执行一个脚本,您创建一个新进程sh(拥有主机 作为父亲的节目)
  • 当您的shell脚本调用外部时 程序/命令它创建一个新的进程(有脚本) 执行shell为父)

如您所知,层次结构可能会非常快。如果系统上有命令pstree,则可以从shell调用它以显示当前进程层次结构。这可能有助于你掌握它。

一个关键特性是任何进程都有一个环境 - 由其环境变量集及其相应的值构成。

这是一个大秘密:当一个流程启动另一个流程时,新流程会继承其父亲环境的副本。由于它是一个副本, 子进程可以通过自己的环境做到它想要的,这不会改变它的父环境。也不是它的祖父,也不是它的曾祖父,也不是......)


故事的寓意是,一个过程不能使用环境变量与其任何祖先进行沟通

由于这是您的需要,您将不得不依赖其他策略:

  • 您可能希望通过standard streamsstdout)进行通信,因为进程可以读取其子输出。或者(这实际上是变体)使用named pipe
  • 如果你想要更详细的东西,现代系统有一堆IPC,如shared memory。但那些不适合与 shell脚本进行通信。
  • 最后,您可能依赖(或多或少)专用系统:message queue(RabbitMQ,ZeroMQ,...),共享缓存(memcached,...),数据库,..但鉴于你的目的,这些可能太重了。