(3 jawaban)
Tutup 2 tahun lalu.
Konteks pertanyaan:Menurut spesifikasi POSIX, ARG_MAX maksimum panjang argumen baris perintah ke exec()
keluarga fungsi. Yang membuat saya percaya bahwa itu adalah angka yang sebenarnya argumen, namun itu jelas tidak berhasil:
$ ulimit -s
8192
$ touch {1..18000}.jpg
$ rm *.jpg
$
Jelas, ini berfungsi dengan baik, meskipun panjangnya lebih dari 8192 item. Menurut jawaban D.W., 8192
seharusnya ukuran dalam kB. Jadi jelas anggapan sebelumnya salah.
Di sinilah pertanyaan sebenarnya muncul:Bagaimana cara mengetahui jumlah item yang sebenarnya akan mendapatkan di atas batas 8192 kB? Dengan kata lain, perhitungan seperti apa yang harus saya lakukan untuk memastikan bahwa *.jpg
jenis glob akan menghasilkan Argument list too long
kesalahan ?
Harap dicatat, ini bukan duplikat dari Apa yang mendefinisikan ukuran maksimum argumen perintah tunggal. Saya tahu tentang getconf ARG_MAX
dan ulimit -s
nilai, itu bukan pertanyaan saya. Saya perlu tahu cara menghasilkan argumen yang cukup dalam ukuran yang akan melebihi batas . Dengan kata lain, saya perlu menemukan cara untuk mendapatkan kesalahan, bukan menghindarinya.
Jawaban yang Diterima:
Menggunakan getconf ARG_MAX
untuk menghasilkan daftar panjang x
dan memanggil utilitas eksternal dengan itu sebagai argumennya akan menghasilkan kesalahan "Daftar argumen terlalu panjang":
$ /bin/echo $( perl -e 'print "x" x $ARGV[0]' "$(getconf ARG_MAX)" )
/bin/sh: /bin/echo: Argument list too long
Lingkungan dan panjang string /bin/echo
akan disertakan dalam apa yang membuat kesalahan terjadi, jadi kita dapat mencoba mencari bilangan terbesar yang mungkin dengan mengurangkan ini:
$ env
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11R6/bin:/usr/local/bin
(Saya memulai shell ini dengan env -i sh
, jadi hanya ada PATH
variabel di lingkungan)
$ /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
Masih terlalu lama. Berapa?
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
Loop ini keluar untuk i=8
.
Jadi ada empat byte yang tidak dapat segera saya perhitungkan (empat dari delapan harus untuk nama dari PATH
variabel lingkungan). Ini adalah terminator nol untuk empat string PATH
, nilai PATH
, /bin/echo
dan string panjang x
karakter.
Perhatikan bahwa setiap argumen diakhiri dengan null, jadi semakin banyak argumen yang Anda miliki untuk perintah, semakin pendek panjang gabungannya.
Juga, hanya untuk menunjukkan efek dari lingkungan yang besar:
$ 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