偶尔,当我有一个生成大型数组的程序时,我会遇到这个错误,每个命令都会抛出错误 “参数列表太长” 即使我只输入:
$ cp
-bash: /bin/cp: Argument list too long
$
我无法使用ls
,甚至无法使用vim
打开新文件:
$ vim test.txt
-bash: /usr/bin/vim: Argument list too long
$
我尝试使用“等待”来完成所有bg进程,但没有更改。它似乎发生不一致,但是当它发生时,唯一的解决方法是重新启动shell。
有什么想法可能会发生什么?
更新:我做了一些进一步的测试,我得到的错误是可重复的。当递归定义的数组长度达到85个元素时,就会发生这种情况。抛出错误的第一个命令是bc
,它甚至不依赖于数组!然后从那里开始,几乎所有其他命令都会抛出相同的错误。
更新:我正在使用的程序有很多bash脚本一起工作,但我已经确定问题总是出现在这个:
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
}
错误通常始于第一个cp
或bc
此函数的第80-90次调用。我已经评论了所有数组操作,因此数组太大会造成这种情况。环境保持在~100-200 Kb,这也不是问题。
答案 0 :(得分:14)
该错误消息有点误导。它应该说“参数列表和环境使用太多空间”。
环境包含您导出的所有环境变量,以及shell启动的环境。通常情况下,环境应该只有几千字节,但是没有什么可以阻止你export
一个百万字节的字符串,如果这样做,你将用完所有允许的空间。
系统允许参数+环境有多大空间并不完全明显。您应该可以使用getconf ARG_MAX
查询限制,使用Gnu xargs
可以从xargs --show-limits </dev/null
获取更多信息(在这两种情况下,假设您没有超出限制:)) ,但有时可用的实际空间将小于指示的值。
无论如何,尝试将兆字节填入环境并不是一个好主意。如果您想要这样做,请将数据放在临时文件中,然后只导出文件名。
答案 1 :(得分:1)
既然你说过当你有一个生成大型数组的程序时,就会遇到这个错误,每个命令都会抛出错误&#34;参数列表太长&#34;。所以,我假设您执行的最后一个命令导致下一个命令出现问题。我的建议是不要对任何命令使用大型参数列表。这可能导致环境溢出,甚至导致下一个命令出现问题。使用包含数据列表的文件而不是大型arg列表,并使用重定向的文件进行输入,如下所示:
command < inputfile