首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >每个命令的“参数列表太长”

每个命令的“参数列表太长”
EN

Stack Overflow用户
提问于 2014-10-09 09:31:32
回答 2查看 11.5K关注 0票数 3

有时,当我有一个生成大型数组的程序时,我会得到这个错误,其中每个命令都会抛出错误“参数列表太长”,即使我只是输入:

代码语言:javascript
复制
$ cp
-bash: /bin/cp: Argument list too long
$

我不能使用ls,甚至不能用vim打开新文件

代码语言:javascript
复制
$ vim test.txt
-bash: /usr/bin/vim: Argument list too long
$

我尝试使用"wait“等待所有bg进程完成,但没有任何更改。这似乎是不一致的,但当它发生时,唯一的修复方法是重新启动shell。

你知道可能发生了什么吗?

更新:我做了一些进一步的测试,我得到的错误是可重复的。当递归定义的数组长度达到85个元素时,就会发生这种情况。抛出错误的第一个命令是一个甚至不依赖于数组的bc!从那时起,几乎所有其他命令都会抛出相同的错误。

更新:我正在使用的程序有许多bash脚本一起工作,但我发现问题总是出现在这个脚本中:

代码语言:javascript
复制
function MPMDrun_prop()
{
PARDIR=$1
COMPDIR=$2
runSTR=$3
NUMNODES=$4
ForceRun=$5

if [ $# -le 3 ] ; then
echo "USAGE: MPMDrun_prop \$PARDIR \$COMPDIR \$runSTR \$NUMNODES \$ForceRun"
fi
echo "in MPMDrun_Prop"
. $PARDIR/ParameterScan.inp
. $MCTDHBDIR/Scripts/get_NumberOfJobs.sh

if [ "$MPMD" != "T" ]; then
  MPMDnodes=1
fi

## If no runscripts in the $PARDIR, copy one and strip of the line which runs the program
if [ -z "$(ls $PARDIR/run*.sh 2> /dev/null)"  ] ; then

 if [ "$forhost" == "maia" ]; then
   cp $MCTDHBDIR/../PBS_Scripts/run-example-maia.sh $PARDIR/run.tmp
   sed 's|mpirun.*||' < $PARDIR/run.tmp > $PARDIR/run.sh
   jobtime=86400
 elif [ "$forhost" == "hermit" ]; then
   cp $MCTDHBDIR/../PBS_Scripts/run-example-hermit.sh $PARDIR/run.tmp
   sed 's|aprun.*||' < $PARDIR/run.tmp > $PARDIR/run.sh
   jobtime=86400
 elif [ "$forhost" == "hornet" ]; then
   cp $MCTDHBDIR/../PBS_Scripts/run-example-hornet.sh $PARDIR/run.tmp
   sed 's|aprun.*||' < $PARDIR/run.tmp > $PARDIR/run.sh
   jobtime=86400
 elif [ "$forhost" == "bwgrid" ]; then
   cp $MCTDHBDIR/../PBS_Scripts/run-example-BWGRID.sh $PARDIR/run.tmp
   sed 's|mpirun.*||' < $PARDIR/run.tmp > $PARDIR/run.sh
   jobtime=86400
 fi
 sed 's|nodes=[0-9]*|nodes=0|' < $PARDIR/run.sh > $PARDIR/run.tmp
 sed 's|#PBS -N.*|#PBS -N MONSTER_'$MonsterName'|' < $PARDIR/run.tmp > $PARDIR/run.sh_

 rm $PARDIR/run.sh
 rm $PARDIR/run.tmp
 chmod 755 $PARDIR/run.sh_
 echo ". $MCTDHBDIR/Scripts/RunFlagSleeper.sh" >> $PARDIR/run.sh_
 ## Include check_convergence.sh for mixed relax/prop compatibility
 echo ". $MCTDHBDIR/Scripts/check_convergence.sh" >> $PARDIR/run.sh_
 echo "RunFlagSleeper $jobtime " >> $PARDIR/run.sh_
 echo "(" >> $PARDIR/run.sh_
 cp $PARDIR/run.sh_ $PARDIR/run1.sh
fi
### Add $runSTR to the most recent runscript
### find runscript$N.sh (run1.sh, run 2.sh, etc)  that has numnodes less than $MPMDnodes
for qq in $(ls $PARDIR/run[0-9]*.sh | sort -g ); do
  NodesInRun=$(cat $qq | grep -o "nodes *= *[0-9]*" | grep -o "[0-9]*")
  if [ "$NodesInRun" -lt "$MPMDnodes"  ]; then
   ## The number of nodes already specified in the runscript doesnt exceed the maximum, so add on another job
   NewNodes=$(echo "$NodesInRun+$NUMNODES" | bc)
   ## Start each aprun command in its own subshell
   ## wait for 24 hrs after aprun, to guarantee that no subshell finishes before the job is done
   sed 's|nodes=[0-9]*|nodes='$NewNodes'|' < $qq > $qq-1
   sed 's|\(RunFlagSleeper .*\)|\1 '$COMPDIR'|' <$qq-1 >$qq
   rm $qq-1
     echo "  (" >> $qq
     ## Sleeps for $jobtime - 5 mins, then removes runflag. in case aprun doesnt finish in $jobtime 
     echo "    cd $COMPDIR" >> $qq
     echo "    $runSTR" >> $qq
     ## remove runflag after aprun command has finished
     echo "    rm $COMPDIR/RunFlag" >> $qq
#     echo "sleep $jobtime" >> $qq-1
     echo "  ) &" >> $qq
#   mv $qq-1 $qq
   ## put a flag in the computation directory so it isnt computed multiple times
   touch $COMPDIR/RunFlag

   if [[ "$NewNodes" -ge "$MPMDnodes" || "$ForceRun" == "T"  ]]; then
    ## This last process made the nodecount exceed the maximum, or there is a ForceRun flag passed
    ## So now, exceute the runscript and start another
    echo "  wait" >> $qq
    echo ") &" >> $qq
    echo "PID=\$!" >> $qq
    echo "wait \$PID" >> $qq
    ## Ensure the queue has room for the next job, if not, wait for it
   Njobs=$(get_NumberOfJobs $runhost)
   while [ "$Njobs" -ge "$maxjobs" ]; do
    echo "Njobs=$Njobs and maxjobs=$maxjobs"
    echo "Waiting 30 minutes for que to clear"
    sleep 1800
   done
    echo "qsub $qq"
#    qsub $qq
    RunCount=$(echo $qq | grep -o 'run[0-9]*.sh' | grep -o '[0-9]*')
    let "RunCount++"
    cp $PARDIR/run.sh_ $PARDIR/run$RunCount.sh
   fi
  fi
done
} 

错误通常在第一个cpbc处调用此函数的第80-90次时开始。我已经注释了所有的数组操作,所以这是由于数组太大而导致的可能性为零。环境保持在大约100-200KB,所以这也不是问题。

EN

回答 2

Stack Overflow用户

发布于 2014-10-09 12:05:48

这个错误消息有点误导人。它应该说“参数列表和环境使用了太多的空间”。

该环境包括您导出的所有环境变量,以及启动shell时所使用的环境。通常情况下,环境应该只有几千字节,但是没有什么可以阻止您对一个百万字节的字符串执行export操作,如果这样做,就会用完所有允许的空间。

系统为参数+环境留出了多少空间,这一点并不是很明显。您应该能够使用getconf ARG_MAX查询限制,使用Gnu xargs您可以从xargs --show-limits </dev/null获得更多信息(在这两种情况下,假设您没有超过限制: ),但有时实际可用空间将会比指示的少。

在任何情况下,试图在环境中填充兆字节都不是一个好主意。如果您想这样做,那么将数据放在一个临时文件中,然后导出该文件的名称。

票数 18
EN

Stack Overflow用户

发布于 2014-10-09 12:09:25

因为你说过,当你有一个生成大型数组的程序时,你会得到这个bug,其中每个命令都会抛出错误“参数列表太长”。因此,我假设您执行的上一条命令会导致下一条命令出现问题。我的建议是不要对任何命令使用大的参数列表。这可能会在环境中造成溢出,甚至在执行下一个命令时也会出现问题。不使用大型参数列表,而是使用包含数据列表的文件,并使用重定向的文件进行输入,如下所示:

代码语言:javascript
复制
command < inputfile
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26268969

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档