将环境变量设置为较大的值 -> "Argument list too long"
Setting environment variable to a large value -> "Argument list too long"
在 bash 脚本中,我将环境变量设置为包含 100 万个字符的字符串。我这样做:
export LG=XXXXXXX # ... 1 million X's
在此之后,我可以毫无问题地回显它,即
echo $LG
但是,在此之后我在脚本中尝试 运行 的任何其他不相关命令都会失败,并显示 "Argument list too long" 错误。例如:
cat randomfile.txt
/bin/cat: Argument list too long
我已经阅读了其他建议使用 xargs 来解决此类问题的帖子,但我没有成功。如果我使用 echo 以外的任何命令,那么我会收到 "Argument list too long" 错误,即使我在设置 $LG 变量后实际上并没有使用它也是如此。我当然想用$LG这个变量,但是设置后不使用也会报错
任何提示将不胜感激,谢谢!
编辑:
我要解决的总体问题是这样的:
我有一个文本文件,需要尽可能小(即几 MB)。此文本文件包含一组封装在特定网络协议中的消息(即 header、消息长度、消息本身)。消息本身可以是长度为 100 万或更多的字符串。因此,为了保持原始文件较小,而不是在文件中包含大消息的多个副本,我使用了一个映射。 IE。如果我在消息字段中看到字母 A,我会使用 sed 查找 A 并将其替换为 100 万个 X。像这样:
cat file.txt | sed "s/A/$LG/g" # Replace A with 1 million X's
我最终会 运行 在(非常慢的)模拟器中进行此操作,因此我需要此操作在尽可能少的周期内完成。换句话说,像 awk 这样使用行程计数为 100 万的循环来动态生成 100 万个 X 的实用程序会太慢。这就是为什么我认为环境变量解决方案是最好的。
命令行参数和环境变量都来自同一个 space 池。将环境变量设置得太长,你不再有 space 作为命令行参数——甚至 xargs
,这会将命令行调用分解成更小的分组以尽可能放入池中,可以'当该池完全满时不运行。
所以:不要那样做。例如,您可以将数据存储在一个文件中,并在环境中导出该文件的路径。
顺便说一下,echo
之所以有效,是因为它内置于您的 shell 中。因此,
echo "$LG"
...不需要启动外部进程,因此进程启动时参数列表长度和环境大小的限制不适用。
另一方面,如果你运行
/bin/echo "$LG"
...然后你会再次看到问题。
考虑到对问题的解释,即您实际要完成的任务,让我建议一种既不需要环境 space 也不需要命令行 space:
#!/bin/bash
# ^-- also consider ksh; faster than bash, but also supports <()
# /bin/sh is not usable here, as POSIX sh does not specify <().
lg=... ## DO NOT USE export HERE!
sed -f <(printf '%s\n' "s/A/$lg/g")
在 bash 脚本中,我将环境变量设置为包含 100 万个字符的字符串。我这样做:
export LG=XXXXXXX # ... 1 million X's
在此之后,我可以毫无问题地回显它,即
echo $LG
但是,在此之后我在脚本中尝试 运行 的任何其他不相关命令都会失败,并显示 "Argument list too long" 错误。例如:
cat randomfile.txt
/bin/cat: Argument list too long
我已经阅读了其他建议使用 xargs 来解决此类问题的帖子,但我没有成功。如果我使用 echo 以外的任何命令,那么我会收到 "Argument list too long" 错误,即使我在设置 $LG 变量后实际上并没有使用它也是如此。我当然想用$LG这个变量,但是设置后不使用也会报错
任何提示将不胜感激,谢谢!
编辑:
我要解决的总体问题是这样的:
我有一个文本文件,需要尽可能小(即几 MB)。此文本文件包含一组封装在特定网络协议中的消息(即 header、消息长度、消息本身)。消息本身可以是长度为 100 万或更多的字符串。因此,为了保持原始文件较小,而不是在文件中包含大消息的多个副本,我使用了一个映射。 IE。如果我在消息字段中看到字母 A,我会使用 sed 查找 A 并将其替换为 100 万个 X。像这样:
cat file.txt | sed "s/A/$LG/g" # Replace A with 1 million X's
我最终会 运行 在(非常慢的)模拟器中进行此操作,因此我需要此操作在尽可能少的周期内完成。换句话说,像 awk 这样使用行程计数为 100 万的循环来动态生成 100 万个 X 的实用程序会太慢。这就是为什么我认为环境变量解决方案是最好的。
命令行参数和环境变量都来自同一个 space 池。将环境变量设置得太长,你不再有 space 作为命令行参数——甚至 xargs
,这会将命令行调用分解成更小的分组以尽可能放入池中,可以'当该池完全满时不运行。
所以:不要那样做。例如,您可以将数据存储在一个文件中,并在环境中导出该文件的路径。
顺便说一下,echo
之所以有效,是因为它内置于您的 shell 中。因此,
echo "$LG"
...不需要启动外部进程,因此进程启动时参数列表长度和环境大小的限制不适用。
另一方面,如果你运行
/bin/echo "$LG"
...然后你会再次看到问题。
考虑到对问题的解释,即您实际要完成的任务,让我建议一种既不需要环境 space 也不需要命令行 space:
#!/bin/bash
# ^-- also consider ksh; faster than bash, but also supports <()
# /bin/sh is not usable here, as POSIX sh does not specify <().
lg=... ## DO NOT USE export HERE!
sed -f <(printf '%s\n' "s/A/$lg/g")