当前位置 博文首页 > 我的地盘我做主:【Linux】【编译相关】execvp: /bin/sh: Argume

    我的地盘我做主:【Linux】【编译相关】execvp: /bin/sh: Argume

    作者:[db:作者] 时间:2021-07-15 15:42

    问题背景

    execvp: /bin/sh: Argument list too long问题出现的两种情况:

    • 1、make的时候,如编译Linux内核、驱动、Android版本等较长-I、-D选项的情况;
    • 2、shell操作,涉及较多文件的情况,如删除大量文件时,直接用rm;

    问题原因

    1、错误来源于sysdeps/gnu/errlist.c文件中:

    [ERR_REMAP (E2BIG)] = N_("Argument list too long"),  
    

    可据此找到对应Linux内核中exec.c中返回E2BIG的地方,实际和ARG_MAX有很大关系。
    2、参考APUE,ARG_MAX的值在运行时间不变的值,但值可能不确定。
    ARG_MAX的值实际上和下面参数有关系:

     - MAX_ARG_STRLEN #单个字符串的最大大小
     - MAX_ARG_STRINGS #参数个数的限制
     - MAX_ARG_PAGES #分配给参数的最大页数
     - stack size #堆栈空间
     - ARG_MAX in limits.h #参数的最大长度
    

    实际上,不同内核的版本也有区别。

    几个命令执行情况的例子:

    [qxhgd@localhost]getconf ARG_MAX
    2897152
    [qxhgd@localhost]ulimit -s
    8192
    [qxhgd@localhost]xargs --show-limits 
    Your environment variables take up 4222 bytes
    POSIX upper limit on argument length (this system): 2090882
    POSIX smallest allowable upper limit on argument length (all systems): 4096
    Maximum length of command we could actually use: 2086660
    Size of command buffer we are actually using: 131072
    

    问题解决

    几种思路

    • 修改主机环境:
    • 调整shell命令或makefile本身;

    修改主机环境

    据说,Linux内核可通过修改下面参数来规避,具体没做实验。

    /*
    * MAX_ARG_PAGES defines the number of pages allocated for arguments
    * and envelope for the new program. 32 should suffice, this gives
    * a maximum env+arg of 128kB w/4KB pages!
    */
    #define MAX_ARG_PAGES 32
    

    其他几个参数也可根据需要调整。

    shell操作场景

    • 以rm为例,一般配合xargs利用管道来解决:
      find . -name “" | xargs rm -rf "” 就行

    • 也可以通过shell来执行:

    #!/bin/bash
    # 设定需要删除的文件夹
    RM_DIR='/testdir/to-del-all'
    cd $RM_DIR
    for I in `ls`
    do
      rm -f $I
    

    make场景

    1、对于-I路径

    • 去除冗余的-I路径
      如某模块在增加-I路径的时候,没有确认是否真的需要,只是参考其他模块直接copy的。
    • 将路径包含设法缩短
      如有的路径里有类似这种A/xx/yy…/…/的,就可以优化一下;
      另外,也可以用软链接来缩短路径;
    • 将需要的头文件整合到一个目录中。

    2、对于-D选项

    • 可以将相关-D选项生成.h文件,直接include相关.h文件。

    命令汇总

    getconf ARG_MAX     #查看系统配置参数ARG_MAX
    sys/limits.h #头文件
    xargs --show-limits #xargs查看各种参数的长度
    MAX_ARG_STRLEN  #include/linux/binfmts.h文件
    cat /proc/$$/environ | wc -c #查看环境变量长度;
    ulimit -s  #查看或修改线程默认栈空间
    echo $(( $(getconf PAGE_SIZE)*32 )) ##查看PAGE_SIZE
    

    参考资料

    • linux-unix-arg_max-maximum-length-of-arguments
    • APUE;
    • argmax
    • what-defines-the-maximum-size-for-a-command-single-argument

    如本文对你有些许帮助,欢迎打赏:
    支付宝打赏链接

    cs