无法在执行exec.Command时从操作系统级别查看命令参数。

huangapple go评论107阅读模式
英文:

unable to see command arguments at OS level issued from exec.Command

问题

我的例程应该从相同的go可执行二进制文件(os.Args[0])中启动10个子进程,并添加一些有效的命令行参数。所有进程应该在指定的秒数内运行,该秒数在其中一个参数中指定。

  1. func spinChildProcesses() {
  2. cmdParts := make([]string, 4)
  3. cmdParts[0] = "-c"
  4. cmdParts[1] = os.Args[0]
  5. cmdParts[2] = "--duration"
  6. cmdParts[3] = "10000"
  7. for i := 0; i < 10; i++ {
  8. proc := exec.Command("bash", cmdParts...)
  9. go proc.Start()
  10. }
  11. }
  12. func main() {
  13. // 不显示解析持续时间参数的代码
  14. // 创建10个子进程
  15. go spinChildProcesses()
  16. // 设置进程的持续时间并终止
  17. time.Sleep(time.Second * time.Duration(duration))
  18. fmt.Println(" - 进程正常终止")
  19. }

当运行上述代码时,查看操作系统级别,可以看到参数没有传递。只有我键入的根进程具有参数:

  1. ps -ef | grep my-test-pr
  2. root 3806 14446 0 15:23 pts/1 00:00:00 ./my-test-pr --duration 10000
  3. root 3810 3806 0 15:23 pts/1 00:00:00 ./my-test-pr
  4. root 3811 3806 0 15:23 pts/1 00:00:00 ./my-test-pr
  5. root 3813 3806 0 15:23 pts/1 00:00:00 ./my-test-pr
  6. root 3814 3806 0 15:23 pts/1 00:00:00 ./my-test-pr
  7. root 3818 3806 0 15:23 pts/1 00:00:00 ./my-test-pr
  8. root 3823 3806 0 15:23 pts/1 00:00:00 ./my-test-pr
  9. root 3824 3806 0 15:23 pts/1 00:00:00 ./my-test-pr
  10. root 3829 3806 0 15:23 pts/1 00:00:00 ./my-test-pr
  11. root 3836 3806 0 15:23 pts/1 00:00:00 ./my-test-pr
  12. root 3840 3806 0 15:23 pts/1 00:00:00 ./my-test-pr

有什么想法为什么参数没有传递给子进程,以及如何确保参数传递给子进程?

英文:

My routine is supposed to spin 10 child processes from the same go executable binary (os.Args[0]), adding some command line arguments that are valid. All processes should live for a number of seconds, which is specified in one of the arguments.

  1. func spinChildProcesses() {
  2. cmdParts := make([]string, 4)
  3. cmdParts[0] = &quot;-c&quot;
  4. cmdParts[1] = os.Args[0]
  5. cmdParts[2] = &quot;--duration&quot;
  6. cmdParts[3] = &quot;10000&quot;
  7. for i := 0; i &lt; 10; i++ {
  8. proc := exec.Command(&quot;bash&quot;, cmdParts...)
  9. go proc.Start()
  10. }
  11. }
  12. func main() {
  13. # not showing code that parses duration arg
  14. # create 10 child subprocesses
  15. go spinChildProcesses()
  16. // set a duration to the process and terminate
  17. time.Sleep(time.Second * time.Duration(duration))
  18. fmt.Println(&quot; - process terminating normaly&quot;)
  19. }

When the above is run, looking at OS level I can see the arguments are not carried out. Only the root process has the arguments which I typed:

  1. ps -ef | grep my-test-pr
  2. root 3806 14446 0 15:23 pts/1 00:00:00 ./my-test-pr --duration 10000
  3. root 3810 3806 0 15:23 pts/1 00:00:00 ./my-test-pr
  4. root 3811 3806 0 15:23 pts/1 00:00:00 ./my-test-pr
  5. root 3813 3806 0 15:23 pts/1 00:00:00 ./my-test-pr
  6. root 3814 3806 0 15:23 pts/1 00:00:00 ./my-test-pr
  7. root 3818 3806 0 15:23 pts/1 00:00:00 ./my-test-pr
  8. root 3823 3806 0 15:23 pts/1 00:00:00 ./my-test-pr
  9. root 3824 3806 0 15:23 pts/1 00:00:00 ./my-test-pr
  10. root 3829 3806 0 15:23 pts/1 00:00:00 ./my-test-pr
  11. root 3836 3806 0 15:23 pts/1 00:00:00 ./my-test-pr
  12. root 3840 3806 0 15:23 pts/1 00:00:00 ./my-test-pr

Any idea why and how to ensure the arguments are passed to the children processes ?

答案1

得分: 3

-c bash标志接受一个字符串参数进行解释。由于-c的参数只是字符串os.Args[0],所以bash只执行这个字符串,而忽略了其他参数。

要将要执行的二进制文件的参数提供给bash -c,请将它们连接成一个字符串:

  1. var args []string
  2. args = append(args, os.Args[0])
  3. args = append(args, "--duration")
  4. args = append(args, "10000")
  5. for i := 0; i < 10; i++ {
  6. proc := exec.Command("/bin/bash", "-c", strings.Join(args, " "))
  7. go proc.Start()
  8. }

或者直接执行你的二进制文件,而不需要额外的shell。

英文:

The -c bash flag takes a single string argument to interpret. Since the argument to -c is only the string os.Args[0], that is all bash is executing, and the rest of the args are being ignored.

To provide the arguments to your binary to be executed by bash -c, join them into a single string:

  1. var args []string
  2. args = append(args, os.Args[0])
  3. args = append(args, &quot;--duration&quot;)
  4. args = append(args, &quot;10000&quot;)
  5. for i := 0; i &lt; 10; i++ {
  6. proc := exec.Command(&quot;/bin/bash&quot;, &quot;-c&quot;, stringsJoin(args, &quot; &quot;))
  7. go proc.Start()
  8. }

Or simply exec your binary directly without the extra shell.

huangapple
  • 本文由 发表于 2016年10月24日 23:32:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/40222222.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定