【问题标题】:How do you execute a bash script with "system()" when there are spaces in the file path?当文件路径中有空格时,如何使用“system()”执行 bash 脚本?
【发布时间】:2017-11-18 10:50:17
【问题描述】:

我创建了一个名为“myscript.h”的简单 bash 脚本,我给它一个 .h 扩展名,原因我不会在这里透露。此 bash 脚本位于“/var/ftp/something with spaces”中。

在终端中,我可以输入“/var/ftp/something with spaces/myscript.h”,脚本运行良好。

但是,在我的 C 程序中,我输入了

system("/var/ftp/something with spaces/myscript.h")

它抱怨找不到“/var/ftp/something”。我已使用正斜杠将系统调用更改为以下内容:

system("/var/ftp/something\ with\ spaces/myscript.h")

但是,它仍然抱怨找不到“/var/ftp/something”。假设我无法更改目录名称,我该如何解决这个问题?

谢谢!

【问题讨论】:

  • 尝试使用转义序列 \" 在字符串中添加引号:system("\"/var/ftp/something with spaces/myscript.h\"");
  • 使用 .h 扩展名调用 bash 脚本很有趣...
  • 您可以使用execl("/var/ftp/something with spaces/myscript.h", NULL)(首先使用fork)高效而稳健地运行您的程序。 system() 是为了“方便”,速度较慢,更脆弱,可能有安全隐患。
  • 简短回答:反斜杠由 c-lexer 解释:'\ ' 等于空格。因此,您应该将它们加倍,shell 将看到一个反斜杠加上一个空格。 (或者:使用'\"'\''将整个内容放入转义引号中,就像在其中一个答案中一样)
  • @Izzo:因为 C 在双引号字符串中解析反斜杠,所以实际上需要将每个反斜杠写为 \\。因此,反斜杠转义的命令是system("/var/ftp/something\\ with\\ spaces/myscript.h")。在 POSIXy 系统中,您可以使用单引号,即。 system("'/var/ftp/something with spaces/myscript.h'").

标签: c linux bash


【解决方案1】:

这应该适用于 gcc 版本 5.4.0

system("\'\'/var/ftp/something\\ with\\ spaces/myscript.h\'\'");

【讨论】:

    【解决方案2】:

    只需将文件名放在单引号内

    system("rm '/var/ftp/something with spaces/myscript.h'")
    

    【讨论】:

    • 如果文件路径包含引号,就没有那么简单了。而rmsystem 中是无用的,请使用unlink(2)
    • @thatotherguy: 不,unlink/bin/rm 使用的系统调用(用于文件)
    • 哦,我明白你的意思了。是的,system("rm foo") 是个坏主意,应该替换为 unlink("foo")
    【解决方案3】:

    要运行单个脚本,您可能会避免使用 system(3) 库函数(并使用较低级别的系统调用,例如 fork(2)execve(2)waitpid(2)... 由 system(3) 的实现使用),或者您可以在将脚本名称传递给system(3)引用脚本名称。

    更多详情,请阅读Advanced Linux Programming

    在 Linux 上,system(3) 被记录为 fork 一个 /bin/sh -c 进程。见sh(1p)。那个 POSIX shell 有一些quoting rules。您可以适当地使用双引号和反斜杠。因此,您将构造(并可能检查)传递给system(3) 的字符串(可能使用asprintf(3)snprintf(3)care)。请注意,C 编译器还有(不同的)string literals 引用约定。

    一般来说,您应该避免使用code injection(想象一个顽皮的用户将一些a; rm -rf $HOME &; 输入作为“目录”名称;您不想在奇怪的情况下运行system(3)
    "/var/ftp/a; rm -rf $HOME &;/myscript.h"字符串)

    在您的特定情况下,我建议适当地使用fork(2)execve(2)(也许通过一些精心选择的exec(3) 函数)、waitpid(2)...。这具有避免依赖和运行/bin/sh 的轻微优势,因此可能会稍微快一些(提高一毫秒)。

    更了解Unix shell的作用;例如,阅读bash 中的各种shell expansions(它们类似于POSIX sh 中规定的shell expansions)并注意globbing。见glob(7)

    【讨论】:

      【解决方案4】:

      请注意,您在从 shell 运行时添加了引号。你需要在这里做同样的事情。在您发送到system 的路径名中添加引号:

      system("\"/var/ftp/something with spaces/myscript.h\"")
      

      【讨论】:

      • 我不知道 Linux,但这个技巧在 windows 上不起作用。
      • 它可以在 Linux 上运行,但某些字符(反斜杠、换行符、双引号等)可能需要转义
      猜你喜欢
      • 2021-08-28
      • 1970-01-01
      • 1970-01-01
      • 2021-05-04
      • 2011-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-22
      相关资源
      最近更新 更多