【问题标题】:How to call a C program inside bash script and store its return value to a variable?如何在 bash 脚本中调用 C 程序并将其返回值存储到变量中?
【发布时间】:2015-03-12 12:32:54
【问题描述】:

我有 bash 脚本,我在其中询问用户一些输入,然后我想调用 C 程序几次,并对返回值求和。请注意,我的 C 程序中的 main 函数也有一些 printf 语句,它返回一个整数值。这是我的 bash 脚本的一部分:

 #!/bin/bash

encBER=0

// Some other code where I read the values from the user

for i in $frames;
do
    tempEncBER=$(./enc_ber $bytes $snr $modulation $channel $alamouti)
    encBER=$((encBER + tempEncBER))
done

echo "Total BER is:" $encBER

重点是我要求它执行10次,也就是说frames变量的值是10,但是执行了一次,出现语法错误,然后再次执行,最终的结果是encBER 的值为 0。它根本不在那里存储任何东西。如何在 C 程序的 main 函数中获取 return 语句的值并在 bash 中使用它?

【问题讨论】:

  • enc_ber 是一个 C 程序这一事实根本不相关。
  • 当您说C程序的“返回值”时,您的意思是在main()末尾使用return返回什么?因为你所做的是存储程序发出的标准输出,这是完全不同的。
  • $frames 的值在哪里设置?
  • 如果frame 的值为10,那么for i in $frames 将恰好循环一次,而$i 的值为10
  • 请注意,虽然main() 返回int,但操作系统只返回main() 返回的int 的最低字节值。所以return 257; 来自int main() 最终会以1 出现在shell 中。

标签: c linux bash


【解决方案1】:

程序的返回值存储在$? 变量中。所以你只需要添加每个$?

for i in $frames;
do
    ./enc_ber $bytes $snr $modulation $channel $alamouti
    encBER=$((encBER + $?))
done

注意该值限制为八位,因此最大值为 255。


例如,如果您想捕获大于 255 的整数或浮点数,请使用 stderr 处理您不想要的所有内容 (fprintf(stderr, "Things I don't want\n");),并使用 stdout 打印您想要捕获的返回值。

【讨论】:

  • 这行得通。但是有什么办法可以绕过 255 的限制吗?
  • 我看到的唯一方法是使用您所做的,但将您不想要的打印到 stderr 并输出您想要捕获的内容。
【解决方案2】:

程序的输出不同于它的返回码。返回码一般应为0,表示成功,或非零,表示失败。如果你想要返回码,那么你可以简单地运行程序,然后检查变量$?

./enc_ber $bytes $snr $modulation $channel $alamouti
retVal=$?
# retVal now contains the value passed back from the exit of your program.

注意不要在运行程序和检查结果之间做任何事情,否则$? 的值会再次改变。

另一方面,如果您希望您的程序向标准输出写入一个值,并且这就是您需要获取的输出,那么您必须将输出重定向到一个文件,然后读取文件的内容:

./enc_ber $bytes $snr $modulation $channel $alamouti >./my_file.txt
output=$( cat my_file.txt )
# output now contains whatever enc_ber wrote to stdio

当然,您的程序必须编写您希望捕获的内容。日志行和其他额外的格式会给你带来问题。上面是一个简单的例子 - 由你来解析你的程序输出的任何内容,但上面应该适用于简单的数字输出。

【讨论】:

  • 我正要对此投赞成票,但临时文件完全是多余的。只要output=$(./enc_ber ...) 是要走的路,一旦你固定enc_ber 来打印结果,而不是return()
  • @tripleee:是的,这是一个公平的观点。如果输出很复杂并且需要过滤/解析,我通常会写入一个临时文件 - 稍后删除 - 并单独处理,但对于一个简单的情况,将这两行结合起来非常有意义。谢谢。
【解决方案3】:

你不需要存储它的返回值,它存储在特殊变量? 所以只是

./cprogram
echo $?

这将输出cprogram的退出代码,如果你需要调用另一个程序并保留这个值,你当然可以现在将它分配给一个变量。

【讨论】:

    【解决方案4】:

    如果你有一个输出文件,

    gcc abc.c -o abc
    

    那么你就可以这样做了,

    output=`./abc <agr1> <agr2> <arg3>`
    
    echo $output
    

    【讨论】:

    • object file 是什么意思?一个二进制一个?
    • 如果它采用命令行参数,那么你应该通过同样的方式发送它,但我认为不能像这样存储超过一行的输出。
    • 目标文件是编译后的代码文件,可以像我展示的那样运行
    • 您能否像上面所说的那样在提到它的地方提供一些参考?我真的很感兴趣。另外,请使用@&lt;username&gt; 在评论中通知更新。 :-)
    • 感谢您的链接。其中的第一行读起来像一个目标文件是一个包含目标代码的文件,这意味着_通常不能直接执行的可重定位格式机器代码 _请纠正我。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-07
    • 1970-01-01
    • 2012-08-07
    • 2016-07-10
    • 2020-06-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多