質問のコンテキスト: POSIX仕様 によると、ARG_MAXはexec()
へのコマンドライン引数の最大lengthです関数のファミリー。これは私がそれが実際のnumber引数であると信じるように導いたが、明らかにそれはうまくいかなかった:
$ ulimit -s
8192
$ touch {1..18000}.jpg
$ rm *.jpg
$
明らかに、これは8192項目を超える長さですが、正常に機能します。 D.W。の回答 によると、8192
はおそらくKB単位のサイズです。ですから、以前の仮定は間違いでした。
これが実際の質問の出番です。実際にになるアイテムの量を8192 kB制限を超えて把握するにはどうすればよいですか?言い換えると、*.jpg
タイプのグロブがArgument list too long
エラーになるようにするには、どのような計算を実行する必要がありますか?
これは 単一のコマンド引数の最大サイズを定義するもの の複製ではないことに注意してください。 getconf ARG_MAX
とulimit -s
の値について知っていますが、それは私の質問ではありません。限界を超えるサイズの引数を生成する方法を知る必要があります。つまり、エラーを回避する方法ではなく、エラーを取得する方法を見つける必要があります。
getconf ARG_MAX
を使用してx
の長いリストを生成し、それを引数として外部ユーティリティを呼び出すと、「引数リストが長すぎます」エラーが生成されます。
$ /bin/echo $( Perl -e 'print "x" x $ARGV[0]' "$(getconf ARG_MAX)" )
/bin/sh: /bin/echo: Argument list too long
文字列/bin/echo
の環境と長さは、エラーを発生させる原因に含まれるため、これらを差し引くことで可能な最大数を見つけようとします。
$ env
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11R6/bin:/usr/local/bin
(このシェルはenv -i sh
で始めたので、環境にはPATH
変数しかありません)
$ /bin/echo $( Perl -e 'print "x" x ($ARGV[0] - length($ENV{"PATH"}) - length("/bin/echo"))' "$(getconf ARG_MAX)" )
sh: /bin/echo: Argument list too long
まだ長すぎる。どれくらい?
i=0
while ! /bin/echo $( Perl -e 'print "x" x ($ARGV[0] - length($ENV{"PATH"}) - length("/bin/echo") - $ARGV[1])' "$(getconf ARG_MAX)" "$i" )
do
i=$(( i + 1 ))
done
このループはi=8
で終了します。
したがって、すぐに説明できない4バイトがあります(8つのうち4つは、PATH
環境変数のnameに対応する必要があります)。これらは、4つの文字列PATH
、PATH
の値、/bin/echo
、およびx
文字の長い文字列のnullターミネータです。
each引数はnullで終了するため、コマンドに必要な引数が多いほど、それらを組み合わせた長さを短くできることに注意してください。
また、大きな環境の影響を示すためだけに:
$ export BIG=$( Perl -e 'print "x" x $ARGV[0]' "$( getconf ARG_MAX )" )
$ /bin/echo hello
sh: /bin/echo: Argument list too long
$ /bin/echo
sh: /bin/echo: Argument list too long
多くのLinuxディストリビューションでは、次のコマンドを実行することにより、ARG_MAXの現在の値を確認できます。
getconf ARG_MAX
「引数リストが長すぎます」というメッセージを生成する簡単な方法は、実際には長い引数リストを提供することです。たとえば、私のシステムで
/bin/echo "$(find / -xdev 2> /dev/null)"
動作しますが
/bin/echo "$(find / -xdev 2> /dev/null)" "$(find / -xdev 2> /dev/null)"
作り出す
bash: /bin/echo: Argument list too long
詳細については、スタックオーバーフローの「 rm、cp、mvコマンドの引数リストが長すぎるエラー 」を参照してください。
追伸問題の長さは、引数と環境を格納するために必要な実際のメモリ量です。引数のnumberとは関係ありません。
システム上のすべてのファイルを一覧表示する代わりに、時間がかかり、疎なシステムでは機能しないため、コマンド
/bin/echo {1..200000}
エラーを生成するはるかに速い(163ms)方法です。私にとってARG_MAX
は2097152
(2,097,152、200万のオーダー)ですが、コマンドは引き続きエラーになります。
シェルに{start..end}
がない場合は、やや遅い(ただしファイルのリストよりも速い)を使用できます。
/bin/echo $(seq 1 200000)
いずれかのコマンドが機能しない場合は、機能するまで、bash
がメモリ不足になるまで、またはseq
がそれ以上カウントできないまで、終了値を増やしてください。
新しいシェル(exit
完了時に)を簡単に開始し、制限を低い値(100kバイト)に設定するには、次のようにします。
$ bash
$ ulimit -s 100
使用した例では、エラーが発生する可能性があります。
$ touch {1..100000}.jpg
bash: /usr/bin/touch: Argument list too long
しかし、echo
のようなものを使用することをお勧めします。ビルトインがエラーを引き起こさないかもしれないことを理解してください、このコマンドは正しく動作するはずです:
$ echo {000001..100000}6789
また、バイト数が上記の制限(1.1Mバイト)をはるかに超えていることにも注意してください。
$ echo {000001..100000}6789 | wc -c
1100000
しかし、このコマンドは機能しません:
$ /bin/echo {000001..100000}6789
bash: /bin/echo: Argument list too long
制限は、シェルの環境サイズに追加される引数リストのサイズ(バイト単位)によって設定されます。