【问题标题】:C generates correct shell command, but system() call returns unexpected valuesC 生成正确的 shell 命令,但 system() 调用返回意外值
【发布时间】:2018-11-07 07:42:08
【问题描述】:

我想从 C 中执行这个 shell 命令: var=19; RANDOM=$var; v1=$RANDOM; v2=$RANDOM; echo $var $v1 $v2 Ubuntu shell 返回:19 24421 24549 下一个基于种子的随机数,如预期的那样。然而,

#include <stdio.h>
#include <string.h>

int main (void) {
    char buffer[200];
for( int a = 18; a < 20; a = a + 1 ){   
     snprintf(buffer, sizeof buffer, "%s%d%s", "var=", a, "; RANDOM=$var; v1=$RANDOM; v2=$RANDOM; echo $var $v1 $v2");
    printf("%s\n", buffer);
     system(buffer);
    }
    return 0;
}

var=18; RANDOM=$var; v1=$RANDOM; v2=$RANDOM; echo $var $v1 $v2 18 18 18 var=19; RANDOM=$var; v1=$RANDOM; v2=$RANDOM; echo $var $v1 $v2 19 19 19

命令字符串正确,但值未更新。是什么导致了这种行为?


以防万一。 System() 调用可以用于临时脚本(例如这个),但不应该在生产中使用,因为它资源繁重且不安全。

【问题讨论】:

  • 这很可能意味着system 没有运行与您相同的shell。 (您暗示您正在运行bash;很可能system() 正在运行sh,而sh 可能是dash 或其他一些shell。)有更好的方法在C 中生成随机数,而无需运行system() — 尽管在 C 中生成随机数的某些方法也存在缺陷。当你看到system() 时,想想“慢”。有时这是做事的好方法;有时(而且,IMO,这是其中之一)它不是。

标签: c bash terminal


【解决方案1】:

Ubuntu(自 18.04 起)带有三个独立的 Bourne 样式 shell。

这里有功能丰富的bash,用作默认用户登录shell:

$ bash -c 'var=19; RANDOM=$var; v1=$RANDOM;  v2=$RANDOM; echo $var $v1 $v2'
19 24421 24549

您有 BusyBox 的嵌入式 ash,用于提前启动:

$ busybox ash -c 'var=19; RANDOM=$var; v1=$RANDOM;  v2=$RANDOM; echo $var $v1 $v2'
19 31262 30375

还有快速精简的dash,用作系统默认shell:

$ dash -c 'var=19; RANDOM=$var; v1=$RANDOM;  v2=$RANDOM; echo $var $v1 $v2'
19 19 19

由于RANDOM 不是标准的shell 功能,因此它们之间的行为不同。 Bash 和 Ash 给出了两个不同的随机序列,而 Dash 只是将其视为常规变量。

当你打开一个终端时,shell 是bash。当您调用system() 时,它会调用/bin/sh,在Ubuntu 上是dash。这就是它与众不同的原因。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-17
    相关资源
    最近更新 更多