如何绕过Linux“Too Many Arguments”限制
我必须将256Kb的文本作为参数传递给“aws sqs”命令,但是在命令行中运行的限制大约为140Kb.这已在许多地方讨论过
it been solved in the Linux kernel as of 2.6.23 kernel.
但无法让它发挥作用.我使用的是3.14.48-33.39.amzn1.x86_64 这是一个简单的测试示例: #!/bin/bash SIZE=1000 while [ $SIZE -lt 300000 ] do echo "$SIZE" VAR="`head -c $SIZE < /dev/zero | tr ' ' 'a'`" ./foo "$VAR" let SIZE="( $SIZE * 20 ) / 19" done 而foo脚本只是: #!/bin/bash echo -n "$1" | wc -c 而我的输出是: 117037 123196 123196 129680 129680 136505 ./testCL: line 11: ./foo: Argument list too long 143689 ./testCL: line 11: ./foo: Argument list too long 151251 ./testCL: line 11: ./foo: Argument list too long 159211 那么,如何修改testCL脚本的问题是它可以传递256Kb的数据?顺便说一句,我试过在脚本中添加ulimit -s 65536并没有帮助. 如果这是完全不可能的,我可以解决这个问题,但是你可以从上面的链接中阐明这个引用
解决方法
编辑:
我终于能够将< = 256KB作为单个命令行参数传递(参见底部的编辑(4)).但是,请仔细阅读我是如何做到的,并自行决定这是否是您想要的方式.至少你应该能够理解为什么你被我发现的“卡住”了. 随着ARG_MAX与ulim -s / 4的耦合,引入了MAX_ARG_STRLEN作为最大值.参数的长度: /* * linux/fs/exec.c * * Copyright (C) 1991,1992 Linus Torvalds */
#ifdef CONFIG_MMU /* * The nascent bprm->mm is not visible until exec_mmap() but it can * use a lot of memory,account these pages in current->mm temporary * for oom_badness()->get_mm_rss(). Once exec succeeds or fails,we * change the counter back via acct_arg_size(0). */
static bool valid_arg_len(struct linux_binprm *bprm,long len) { return len <= MAX_ARG_STRLEN; }
#else
static bool valid_arg_len(struct linux_binprm *bprm,long len) { return len <= bprm->p; } #endif /* CONFIG_MMU */
static int copy_strings(int argc,struct user_arg_ptr argv,struct linux_binprm *bprm) {
str = get_user_arg_ptr(argv,argc);
len = strnlen_user(str,MAX_ARG_STRLEN); if (!len) goto out; ret = -E2BIG; if (!valid_arg_len(bprm,len)) goto out;
}
MAX_ARG_STRLEN定义为linux / include / uapi / linux / binfmts.h中页面大小的32倍:
/* * These are the maximum length and maximum number of strings passed to the * execve() system call. MAX_ARG_STRLEN is essentially random but serves to * prevent the kernel from being unduly impacted by misaddressed pointers. * MAX_ARG_STRINGS is chosen to fit in a signed 32-bit integer. */ #define MAX_ARG_STRLEN (PAGE_SIZE * 32) #define MAX_ARG_STRINGS 0x7FFFFFFF
默认页面大小为4KB,因此您无法传递超过128KB的参数. 我现在无法尝试,但如果可能在您的系统上切换到巨大的页面模式(页面大小4MB)解决了这个问题. 有关更多详细信息和参考,请参阅this answer至a similar question on Unix & Linux SE. 编辑: (1) (2) (3) (4)
117037 123196 123196 129680 129680 136505 143689 151251 159211
227982 227982 239981 239981 252611 252611 265906 ./testCL: line 11: ./foo: Argument list too long 279901 ./testCL: line 11: ./foo: Argument list too long 294632 ./testCL: line 11: ./foo: Argument list too long 所以现在限制从128KB移动到256KB.我不知道潜在的副作用.据我所知,我的系统似乎运行得很好. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |