【问题标题】:Prevent wildecard expansion with system() function call使用 system() 函数调用防止通配符扩展
【发布时间】:2017-06-13 14:37:50
【问题描述】:

我已阅读此内容:Stop shell wildcard character expansion? 和类似内容 - 这不是重复的问题。

我正在处理一组遗留的 c++ 代码,从中构建了许多二进制文件。这段代码使用system 函数来执行一个shell 脚本,并传递一些参数。不幸的是,事实证明,一些参数可能包含* 字符,但参数没有正确转义。结果,当执行 shell 脚本时,* 被扩展,这不是我想要的。这是一个复制问题的简单代码:

script.sh

#!/bin/bash

i=1
for var in "$@"
do
    echo "$i => $var"
    ((i++))
done

program.cpp

#include <stdlib.h>
#include <string>

int main(int argc, char* argv[])
{
   std::string command = "/tmp/sh/script.sh *";
   return system(command.c_str());
}

当编译的二进制文件执行时,我将文件列表作为参数获取到 shell,而不是星号:

$ ./program
1 => program
2 => program.cpp
3 => script.sh

现在,如果我在 shell 中使用 set -fset -o noglob 关闭 glob 扩展,则直接调用脚本会按预期工作:

$ set -f
$ ./script.sh *
1 => *

但是,当使用system 执行脚本时,这不起作用:

$ set -f
$ ./program
1 => program
2 => program.cpp
3 => script.sh

通过system执行命令时,有什么方法可以防止扩展?

我真的想避免重建二进制文件,因为在操作和管理上这将是一项巨大的工作。

更新:正如我所提到的,我想避免对 cpp 源进行任何更改;我只想在操作系统级别禁用 glob 扩展(通过任何标志、更改的文件等 - 如果需要,我很乐意修改盒子上的任何文件)。

【问题讨论】:

  • 您可以使用自己的影子库system() 函数。
  • 难道shell不能让你在同一行执行两个命令吗?
  • @AleksG 不,不需要更改源,只需重新链接。如果可以注入共享库,也可以避免重新链接。
  • 您可以使用自己的system()函数创建一个共享库,并通过LD_PRELOAD var添加它
  • @Aleks G. 我确实看到了。但有时重构一堆代码以获得更好的解决方案是值得的。 :-)

标签: c++ linux bash shell wildcard-expansion


【解决方案1】:

为了结束循环,因为 Slava 没有发布答案......从他的评论中复制:

您可以使用自己的system() 函数创建一个共享库并通过LD_PRELOAD var 添加它

我最终使用了这种方法 - 效果非常好。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-09
    • 2012-07-12
    • 2022-11-04
    • 1970-01-01
    • 2013-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多