Saya menemukan bahwa ini akan menimbulkan kesalahan "argumen terlalu lama":
ls *.*
Dan ini tidak akan meningkatkannya:
for file in *.*
do
echo $file
done
Mengapa?
Saya menemukan bahwa ini akan menimbulkan kesalahan "argumen terlalu lama":
ls *.*
Dan ini tidak akan meningkatkannya:
for file in *.*
do
echo $file
done
Mengapa?
Jawaban:
Kesalahan "argumen terlalu panjang" adalah E2BIG, dinaikkan oleh execvepanggilan sistem jika ukuran total argumen (ditambah lingkungan, pada beberapa sistem) terlalu besar. The execvepanggilan adalah salah satu yang dimulai proses eksternal, khususnya loading file executable yang berbeda (ada panggilan yang berbeda, fork, untuk menjalankan proses terpisah yang kode masih dari file eksekusi yang sama). The forLoop adalah shell membangun internal, sehingga tidak melibatkan menelepon execve. Perintah ls *.*memunculkan kesalahan bukan ketika glob diperluas tetapi kapan lsdipanggil.
execvegagal dengan kesalahan E2BIGketika ukuran total argumen ke perintah lebih besar dari ARG_MAX batas . Anda dapat melihat nilai batas ini pada sistem Anda dengan perintah getconf ARG_MAX. (Mungkin Anda dapat melampaui batas ini jika Anda memiliki cukup memori; menjaga dengan ARG_MAXjaminan yang execveakan berfungsi selama tidak ada kesalahan yang tidak terkait terjadi.)
execveBatasan ini ditegakkan oleh kernel, membatasi batasan karena argumen perlu disalin melalui memori kernel pada satu titik dan proses pengguna tidak dapat diizinkan untuk meminta jumlah memori shell yang sewenang-wenang. Di dalam shell, tidak ada alasan untuk memiliki batasan, apa pun yang sesuai dengan memori virtual baik-baik saja.
Saya kira bahwa dalam contoh pertama lsdijalankan dari bashmelalui fork/ execsistem pasangan panggilan, di satu detik, semua kerja adalah internal untuk bash.
The execpanggilan memiliki batas, kerja internal dari bashbukannya belum (atau lebih baik, memiliki batas yang berbeda yang tidak ada hubungannya dengan exec, mungkin jumlah memori yang tersedia).
execdalam /usr/include/linux/limits.hbiasanya, didefinisikan sebagai ARG_MAX.
Karena dalam kasus lsitu adalah argumen, dan jumlah argumen terbatas.
Dalam hal forsiklus, itu hanya daftar item. Tidak ada batasan (sejauh yang saya ketahui) untuk itu.
for i in {00000001..20000000} ;do ((10#$i==1)) && break; done
/bin/bashvs./bin/sh(yang mungkin merupakan tautan ke dasbor)?