为什么在传递带引号的参数时会收到“/bin/sh:参数列表太长”?

2023-12-10

可以传递到的命令行有多长sh -c ''? (在 bash 和 bourne shell 中)

该限制远低于操作系统的限制(对于现代 Linux)。

例如:

$ /bin/true $(seq 1 100000)
$ /bin/sh -c "/bin/true $(seq 1 100000)"
bash: /bin/sh: Argument list too long

我该如何规避这个问题?

Update

我想指出的是getconf在这里无法提供帮助(因为这不是系统限制):

$ seq 1 100000 | wc -c
588895
$ getconf ARG_MAX
2097152

更新#2

现在我明白了这里的重点是什么。这不是 shell 限制,而是系统限制,但针对每个参数的长度,而不是针对整个 arglist。

$ /bin/true $(seq 1 100000)
$ /bin/true "$(seq 1 100000)"
bash: /bin/true: Argument list too long

谢谢 CodeGnome 的解释。


TL;DR

单个参数必须短于 MAX_ARG_STRLEN。

Analysis

根据这个链接:

作为自 2.6.23 起的附加限制,一个参数的长度不得超过 MAX_ARG_STRLEN (131072)。如果您生成像“sh -c '使用长参数生成'”这样的长调用,这可能会变得相关。

这正是OP指出的“问题”。虽然允许的参数数量可能非常大(请参阅getconf ARG_MAX),当您将带引号的命令传递给/bin/shshell 将引用的命令解释为单个字符串。在OP的示例中,正是这个单个字符串超出了 MAX_ARG_STRLEN 限制,而不是扩展参数列表的长度。

具体实施

参数限制是特定于实现的。然而,这篇 Linux 期刊文章提出了几种解决这些问题的方法,包括增加系统限制。这可能并不直接适用于 OP,但它在一般情况下仍然有用。

做点别的事

OP的问题实际上并不是一个真正的问题。问题在于施加任意约束,但无法解决现实世界的问题。

您可以通过使用循环轻松解决这个问题。例如,对于 Bash 4:

for i in {1..100000}; do /bin/sh -c "/bin/true $i"; done

工作得很好。它肯定会很慢,因为您在每次循环时都会生成一个进程,但它肯定会绕过您遇到的命令行限制。

描述您的真正问题

如果循环不能解决您的问题,请更新问题以描述您实际尝试使用很长的参数列表解决的问题。探索任意行长度限制是一项学术活动,而不是 Stack Overflow 的主题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么在传递带引号的参数时会收到“/bin/sh:参数列表太长”? 的相关文章

  • Bash 完成脚本在某些参数选项后完成文件路径

    我正在为命令行工具编写 bash 完成脚本 plink local cur prev opts COMPREPLY cur COMP WORDS COMP CWORD prev COMP WORDS COMP CWORD 1 opts 1
  • 参考当前命令的先前参数

    例如 我想执行以下操作 mv xxxx xxxx bak 我知道我可以使用这个命令 mv xxxx bak 我认为这在某种程度上并不直接 如果我能做到这一点那就太好了 mv xxxx 1 bak 有时我需要这样 echo xxxx yyyy
  • TeamCity 命令行构建运行程序:如何使构建失败?

    我们使用 TeamCity 的命令行构建运行程序来调用 bat 文件 bat 文件通过调用 Visual Studio 2008 的 devenv exe 来构建我们的解决方案 然后执行单元测试并创建正确的文件夹结构 我们想要做的是 如果对
  • C 编程:正向变量参数列表

    我正在尝试编写一个函数 它接受可变数量的参数 如 printf 执行一些操作 然后将变量列表传递给 printf 我不知道如何做到这一点 因为它似乎必须将它们推入堆栈 大约是这样的 http pastie org 694844 http p
  • 在composer.json中运行命令行命令

    我正在尝试编写一个composer json 文件 该文件将连续运行多个命令行命令 作为一个示例 如下所示 scripts test createDir createDir mkdir testing 当我在终端中运行作曲家文件时使用com
  • 使用 sed 将 old-link-url 替换为 new-link-url

    我正在 bash 中编写一个脚本 将 old link url 替换为 new link url 我的问题是 sed 由于斜杠而无法替换 url 如果我只输入一些文字就可以了 my code sed e s old link new lin
  • 如何使用 bash 脚本关闭所有终端,在每个终端中有效地按 Ctrl+Shift+Q

    我经常打开许多终端 其中一些正在运行重要的进程 例如服务器 而另一些则没有运行任何东西并且可以关闭 如果您按 重要 则会弹出确认提示Cntrl Shift Q在其中 如下所示 我想要一个 bash 脚本 它可以关闭所有终端 但将 重要 终端
  • sed-删除不包含模式的行

    我很惊讶我在 SO 上找不到与此类似的问题 如何使用 sed 删除所有不包含特定模式的行 例如 我有这个文件 cat kitty dog giraffe panda lion tiger 我想要一个 sed 命令 当调用该命令时 它将删除所
  • ANSI 转义码在行尾有奇怪的行为

    重现步骤 考虑以下 shell 命令 echo e e 41mTest nTest2 e 0mTest3 它打印Test并在下一行中Test2具有红色背景 使用 ANSI 转义码 Test2后面直接是Test3这是无色的 行为 第一次执行此
  • 如何使用命令终止上次打开的 Internet Explorer 窗口?

    我正在尝试编写一个 Windows 命令文件来在 IE 中打开网页 等待其加载 然后关闭 IE 窗口 以下方法有效 但会杀死所有 IE 窗口 因此运行 cmd 之前已打开的所有 IE 窗口也将被关闭 start iexplore exe p
  • 如何将命令行参数传递给 rake 任务

    我有一个 rake 任务需要将一个值插入到多个数据库中 我想从命令行或从another耙任务 我怎样才能做到这一点 您可以通过向任务调用添加符号参数来指定 rake 中的形式参数 例如 require rake task my task a
  • Windows、Emacs、Git Bash 和 shell 命令

    Windows 7 Emacs 24 3 1 git 1 8 1 msysgit 1 我的等效 emacs 文件中有以下内容 if equal system type windows nt progn setq explicit shell
  • 使用 Jenkins 运行 ios-sim

    我正在尝试使用以下命令从命令行启动我的应用程序ios sim https github com downloads pegli ios sim ios sim xcode4 3 tar gz但这就是我得到的 Started by user
  • 从 bash 脚本运行节点

    很简单 我正在尝试使用 cron 自动运行 nodejs 脚本 但是脚本本身似乎无法运行该文件 我的脚本很简单 usr bin env node node var node assets js update js 但是 在运行此命令时 它返
  • 向伪 shell (pty) 发出命令

    我尝试使用 subprocess popen os spawn 来运行进程 但似乎需要伪终端 import pty master slave pty openpty os write master ls l 应该发送 ls l 到从属终端
  • 使用Sed查找并替换json字段

    我有一组 json 文件 其中在最后一个键值对之后有需要替换的逗号 RepetitionTime 0 72 TaskName WM Manufacturer Siemens ManufacturerModelName Skyra Magne
  • Bash:循环遍历字符串数组后无法读出带空格的字符串

    我正在使用循环读取数组的内容 该数组包含名为 music 的目录层次结构中的所有目录和文件 内容是 find 命令先前输出的字符串 这个想法是根据流派 艺术家和标题将 directory contents 中每个数组元素的完整目录路径分成子
  • `docker run` 输出到 bash 变量 - 奇怪的行为

    我看到一些奇怪的行为从docker run到 bash 变量中 简单的例子 bin bash PWD docker run rm ti ubuntu pwd 2 gt 1 also tried with PWD docker run wit
  • Linux命令列出所有可用命令和别名

    是否有一个 Linux 命令可以列出该终端会话的所有可用命令和别名 就好像您输入 a 并按下 Tab 键一样 但针对的是字母表中的每个字母 或者运行 别名 但也返回命令 为什么 我想运行以下命令并查看命令是否可用 ListAllComman
  • 使用从 java 程序调用的 Windows 命令提示符将具有多个连续空格的字符串作为参数传递给 jar 文件

    我想使用在另一个java程序中调用的Windows命令提示符将带有多个连续空格的字符串作为参数传递给jar文件 java 文件是这样的 它打印它的所有参数 package src public class myClass public st

随机推荐