使用带有长字符串的 `system` VS 多个参数

Using `system` with a long string VS multiple arguments

我运行以下shell命令:

nvim +CheckHealth +'w ~/Desktop/file.txt' +qall

这会调用 nvim (Neovim) 并告诉它 运行 三个连续的命令:

  1. CheckHealth 验证常见错误。它 运行 在缓冲区中。
  2. w ~/Desktop/file.txt 将相同的缓冲区保存到文件中。
  3. qall关闭所有缓冲区。

我正在尝试使用 system 从 ruby 运行 这个。如果我 运行 它作为一个参数,它工作正常:

system("nvim +CheckHealth +'w ~/Desktop/file.txt' +qall")

但是,如果 运行 作为多个参数,它会失败(它 运行s 但不输出文件):

system("nvim", "+CheckHealth", "+'w ~/Desktop/file.txt'", "+qall")

我做错了什么?注意 我不是在寻求解决方法。我有一个解决方法,即将 运行 它作为一个参数。我的问题是 为什么当 运行 作为多个参数 时它不起作用?我对 system 有什么误解?

当您使用 system 的单参数版本时:

system("nvim +CheckHealth +'w ~/Desktop/file.txt' +qall")

您正在启动 shell 并将整个字符串传递给它:

nvim +CheckHealth +'w ~/Desktop/file.txt' +qall

执行。这意味着该字符串中的所有内容都将由 shell;特别是,shell 将处理 +'w ~/Desktop/file.txt' 中的单引号,当 vim 开始解析其参数列表时,它会看到三个如下所示的参数:

  1. +CheckHealth
  2. +w ~/Desktop/file.txt
  3. +qall

system 的多参数版本中:

system("nvim", "+CheckHealth", "+'w ~/Desktop/file.txt'", "+qall")

不会启动 shell(这是一件好事,因为您不必担心 shell 命令注入和转义)所以 +w 参数中的单引号获胜' 被 shell 删除。这意味着 vim 会看到这些参数:

  1. +CheckHealth
  2. +'w ~/Desktop/file.txt'
  3. +qall

大概 vim 对第二个参数中的单引号不满意。

执行摘要:

  • system的单参数版本使用shell来解析命令行,多参数版本根本不使用shell .

  • +'w ~/Desktop/file.txt' 中的单引号是为了防止 shell 将其视为两个参数,它们不存在 vim。

  • 如果您使用的是 system 的多参数版本(您应该这样做),那么您会说:

    system("nvim", "+CheckHealth", "+w ~/Desktop/file.txt", "+qall")
    

    并且不必担心通过 shell.

  • 引用和转义内容