从C ++代码中将多行bash脚本作为字符串运行

时间:2017-07-26 06:44:05

标签: c++ linux bash

我想从C ++代码运行以下bash脚本。我尝试使用system()popen来运行命令并捕获其输出,但是我得到了错误,因为内置的sh试图执行它,例如,

sh: 6: [[: not found
sh: 8: [[: not found
sh: 9: [[: not found

我也尝试了bash -c,但也产生了错误,因为我认为它不会处理多行字符串。

由于多种原因,我无法将脚本放在.sh文件中并运行它。因此,此脚本需要作为字符串存储在C ++代码中并执行。知道如何做到这一点?

#!/bin/bash
for sysdevpath in $(find /sys/bus/usb/devices/usb*/ -name dev); do
    (
        syspath="${sysdevpath%/dev}"
        devname="$(udevadm info -q name -p $syspath)"
        [[ "$devname" == "bus/"* ]] && continue
        eval "$(udevadm info -q property --export -p $syspath)"
        [[ -z "$ID_SERIAL" ]] && continue
        [[ "${ID_SERIAL}" == *"PX4"* ]] && echo "/dev/$devname"
    )
done

示例代码:

注意:您可以使用this tool将文本转换为C ++转义字符串。

int main() {
    std::cout << system("#!/bin/bash\nfor sysdevpath in $(find /sys/bus/usb/devices/usb*/ -name dev); do\n    (\n        syspath=\"${sysdevpath%/dev}\"\n        devname=\"$(udevadm info -q name -p $syspath)\"\n        [[ \"$devname\" == \"bus/\"* ]] && continue\n        eval \"$(udevadm info -q property --export -p $syspath)\"\n        [[ -z \"$ID_SERIAL\" ]] && continue\n        [[ \"${ID_SERIAL}\" == *\"PX4\"* ]] && echo \"/dev/$devname\"\n    )\ndone");

    return 0;
}

1 个答案:

答案 0 :(得分:1)

您可以将多行脚本转换为单行。我们假设您有以下脚本:

FOO=`uname`
if [ "$FOO" == "Linux" ]; then
    echo "You are using 'Linux'"
fi

上面的代码可以使用分号转换为单行:

FOO=`uname`; if [ "$FOO" == "Linux" ]; then echo "You are using 'Linux'"; fi

现在通过适当的转义,您可以使用system命令从程序执行它,如下所示:

#include <cstdlib>
#include <string>

int main() {
    std::string foo {
        "bash -c '"
        "FOO=`uname`; "
        "if [ \"$FOO\" == \"Linux\" ]; then "
        "echo \"You are using 'Linux'.\"; "
        "fi'"
    };
    system(foo.c_str());
}

请注意,相邻的字符串文字由编译器连接,因此您仍然可以使其看起来像多行脚本,以提高可读性。