是什么导致GNU Make脱壳 [英] What causes GNU Make to shell out

查看:85
本文介绍了是什么导致GNU Make脱壳的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

GNU如何决定是直接根据规则还是通过批处理文件运行一条线?我在Windows Server 2008平台上使用GNU Make v3.80,所以我的外壳是cmd.exe.

How does GNU make decide if it runs a line from a rule directly or via a batch file? I'm using GNU Make v3.80 on Windows Server 2008 platform, so my shell is cmd.exe.

打开调试(-d)并注意到规则中的某些行不是通过子外壳运行的(在我的情况下是使用cmd.exe进行批处理),而是由make直接调用的.

Switching on debugging (-d) and noticed that some lines from within a rule are not run via a sub-shell (batch in my case as using cmd.exe) but appear to be called directly by make.

请参见下面的示例.查看如何直接运行xcopy命令:

See example below. See how the xcopy command is run directly:

CreateProcess(C:\Windows\system32\xcopy.exe,xcopy /?,...)

但是echo命令是通过批处理文件运行的:

But the echo command is run via a batch file:

Creating temporary batch file C:\Users\fbloggs\AppData\Local\Temp\95\make732002.bat

makefile示例:

Example makefile:

stackoverflow :
    xcopy /?
    @echo Done

完整的dDebug输出:

Full dDebug output:

GNU Make 3.80 Tool Version v1.3  build for Linux on 20060503
Copyright (C) 2002  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
find_and_set_shell path search set default_shell = C:/Windows/System32/cmd.exe
Reading makefiles...
Reading makefile `..\..\..\pi_scripts\make\make_shell.mak'...
Updating makefiles....
 Considering target file `..\..\..\pi_scripts\make\make_shell.mak'.
  Looking for an implicit rule for `..\..\..\pi_scripts\make\make_shell.mak'.
  No implicit rule found for `..\..\..\pi_scripts\make\make_shell.mak'.
  Finished prerequisites of target file `..\..\..\pi_scripts\make\make_shell.mak'.
 No need to remake target `..\..\..\pi_scripts\make\make_shell.mak'.
Updating goal targets....
Considering target file `stackoverflow'.
 File `stackoverflow' does not exist.
 Finished prerequisites of target file `stackoverflow'.
Must remake target `stackoverflow'.
xcopy /?
CreateProcess(C:\Windows\system32\xcopy.exe,xcopy /?,...)
Putting child 0x025dc670 (stackoverflow) PID 39739552 on the chain.
Live child 0x025dc670 (stackoverflow) PID 39739552 
Copies files and directory trees.

NOTE: Xcopy is now deprecated, please use Robocopy.

XCOPY source [destination] [/A | /M] [/D[:date]] [/P] [/S [/E]] [/V] [/W]
                           [/C] [/I] [/Q] [/F] [/L] [/G] [/H] [/R] [/T] [/U]
                           [/K] [/N] [/O] [/X] [/Y] [/-Y] [/Z] [/B]
                           [/EXCLUDE:file1[+file2][+file3]...]

  source       Specifies the file(s) to copy.
  destination  Specifies the location and/or name of new files.
<snip>
Reaping winning child 0x025dc670 PID 39739552 
Creating temporary batch file C:\Users\fbloggs\AppData\Local\Temp\95\make732002.bat
CreateProcess(C:\Users\fbloggs\AppData\Local\Temp\95\make732002.bat,C:\Users\fbloggs\AppData\Local\Temp\95\make732002.bat,...)
Live child 0x025dc670 (stackoverflow) PID 39739552 
Done
Reaping winning child 0x025dc670 PID 39739552 
Cleaning up temp batch file C:\Users\fbloggs\AppData\Local\Temp\95\make732002.bat
Removing child 0x025dc670 PID 39739552 from chain.
Successfully remade target file `stackoverflow'.

推荐答案

有趣的问题.尽管由于没有设置重现此环境而没有机会验证我的答案,但是我将根据读取源代码的方式进行尝试.作为参考,下面的行是从GNU make源文件 job复制的.c .

Interesting question. Although I do not have the opportunity to verify my answer because I do not have the environment set up to reproduce this, I will give it a try based on source code reading. For reference, the lines below are copied from the GNU make source file job.c.

首先,该代码指示何时直接执行命令以及何时通过外壳执行命令.

First of all, that code indicates when a command is executed directly and when it is executed via the shell.

3470 /* Figure out the argument list necessary to run LINE as a command.  Try to
3471    avoid using a shell.  This routine handles only ' quoting, and " quoting
3472    when no backslash, $ or ' characters are seen in the quotes.  Starting
3473    quotes may be escaped with a backslash.  If any of the characters in
3474    sh_chars[] is seen, or any of the builtin commands listed in sh_cmds[]
3475    is the first word of a line, the shell is used.

对于您的环境,这两个字符串数组似乎是:

and for your environment, these two arrays of strings seem to be:

2625   static char sh_chars_dos[] = "|&<>";
2626   static char *sh_cmds_dos[] = { "assoc", "break", "call", "cd", "chcp",
2627                                  "chdir", "cls", "color", "copy", "ctty",
2628                                  "date", "del", "dir", "echo", "echo.",
2629                                  "endlocal", "erase", "exit", "for", "ftype",
2630                                  "goto", "if", "if", "md", "mkdir", "move",
2631                                  "path", "pause", "prompt", "rd", "rem", "ren",
2632                                  "rename", "rmdir", "set", "setlocal",
2633                                  "shift", "time", "title", "type", "ver",
2634                                  "verify", "vol", ":", 0 };

上面列表中的任何命令都由"shell"执行-但是,在您的情况下,这实际上并不意味着调用任何shell,而是按照您提到的那样创建此临时批处理文件.在功能construct_command_argv_internal()中,可以找到以下注释和代码:

Any command in the list above is executed by the "shell" -- however, in your case this does not really mean invoking any shell, but creating this temporary batch file as you mentioned. In the function construct_command_argv_internal(), the following comment and code can be found:

3139 #ifdef WINDOWS32
3140         else    /* non-Posix shell (cmd.exe etc.) */
3141           {
3142             const char *f = line;
3143             char *t = line;
3144             char *tstart = t;
3145             int temp_fd;
3146             FILE* batch = NULL;
3147             int id = GetCurrentProcessId ();
3148             PATH_VAR(fbuf);
3149
3150             /* Generate a file name for the temporary batch file.  */
3151             sprintf (fbuf, "make%d", id);
3152             *batch_filename = create_batch_file (fbuf, 0, &temp_fd);
3153             DB (DB_JOBS, (_("Creating temporary batch file %s\n"),
3154                           *batch_filename));

这与您的make运行的输出一致.也许您可以尝试使用sh_cmds_dos列表中的一些命令来检查这是否是正确的分析...

This is in line with the output of your make run. Maybe you can try some of the commands in the sh_cmds_dos list in order to check whether this is a correct analysis...

这篇关于是什么导致GNU Make脱壳的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆