Jika daftar argumen terlalu panjang (ingat, apa * yang diperbesar ke daftar semua file yang cocok dengan bola dunia), Anda dapat menyiasatinya dengan menggunakan misalnya IFS="\n" for file in /src/*; do mv "$file" /dst/; doneatau rsync -a /src/ /dst/.
DopeGhoti
Jawaban:
18
Itu sangat tergantung pada sistem dan versi, pada jumlah dan ukuran argumen dan pada jumlah dan ukuran nama variabel lingkungan.
Secara tradisional pada Unix, batas (seperti yang dilaporkan oleh getconf ARG_MAX) lebih atau kurang pada ukuran kumulatif:
Panjang string argumen (termasuk terminating '\0')
Panjang array pointer ke string tersebut, jadi biasanya 8 byte per argumen pada sistem 64bit
Panjang string lingkungan (termasuk terminating '\0'), string lingkungan sedang dengan sesuatu seperti konvensi var=value.
Panjang array pointer ke string tersebut, jadi biasanya 8 byte per argumen pada sistem 64bit
Mengingat yang cpjuga dianggap sebagai argumen (adalah argumen pertama).
Di Linux, itu tergantung pada versinya. Perilaku di sana berubah baru-baru ini di mana itu bukan lagi ruang tetap.
Memeriksa di Linux 3.11, getconf ARG_MAXsekarang melaporkan seperempat dari batas yang ditetapkan pada ukuran stack, atau 128kiB jika itu kurang dari 512kiB).
Batas itu adalah pada ukuran kumulatif argumen dan string lingkungan dan beberapa overhead (saya menduga karena pertimbangan penyelarasan pada batas halaman). Ukuran pointer tidak diperhitungkan.
Mencari batas, saya dapatkan:
$ /bin/true {1..164686}
$ /bin/true {1..164687}
zsh: argument list too long: /bin/true
$ x= /bin/true {1..164686}
$ x=1 /bin/true {1..164686}
zsh: argument list too long: /bin/true
Ukuran kumulatif maksimum sebelum melanggar dalam hal itu adalah:
Sekarang, itu tidak berarti bahwa Anda dapat melewati 1 juta argumen kosong. Pada sistem 64 bit, 1 juta argumen kosong membuat daftar penunjuk 8MB, yang akan berada di atas ukuran tumpukan 4MiB.
(Anda akan melihat itu bukan kesalahan E2BIG. Saya tidak yakin pada titik mana proses tersebut terbunuh di sana, apakah itu ada dalam execvepanggilan sistem atau yang lebih baru).
Perhatikan juga (masih di Linux 3.11) bahwa ukuran maksimum argumen tunggal atau string lingkungan adalah 128kiB, terlepas dari ukuran stack.
$ /bin/true ${(l.131071..a.)${:-}} # 131072 OK
$ /bin/true ${(l.131072..a.)${:-}} # 131073 not
zsh: argument list too long: /bin/true
$ /bin/true ${(l.131071..a.)${:-}} ${(l.131071..a.)${:-}} # 2x 131072 OK
Bisakah Anda berbagi tolong, bagaimana Anda menghasilkan 164686angka? yaitu bagaimana Anda menghitung urutan itu akan berada di bawah 2097152ukuran ARG_MAX?
Sergiy Kolodyazhnyy
14
Itu akan tergantung pada nilai ARG_MAX yang dapat berubah antar sistem. Untuk mengetahui nilai untuk menjalankan sistem Anda (menunjukkan hasil pada tambang sebagai contoh):
$ getconf ARG_MAX
2097152
Ini tidak ada hubungannya dengan cpatau shell Anda, itu adalah batas yang ditentukan oleh kernel, itu tidak akan menjalankan ( exec()) perintah jika argumen mereka lebih panjang dari ARG_MAX. Jadi, jika panjang daftar argumen yang Anda berikan cplebih besar dari ARG_MAX, cpperintah tidak akan berjalan sama sekali.
Untuk menjawab pertanyaan utama Anda, maka tidak cpakan memproses file karena tidak akan pernah dieksekusi dengan banyak argumen. Saya juga harus menyebutkan bahwa ini tidak tergantung pada jumlah argumen tetapi pada panjangnya. Anda mungkin bisa memiliki masalah yang sama dengan nama file yang sangat sedikit tetapi sangat panjang.
Cara mengatasi kesalahan ini adalah dengan menjalankan perintah Anda dalam satu lingkaran:
IFS="\n" for file in /src/*; do mv "$file" /dst/; done
ataursync -a /src/ /dst/
.Jawaban:
Itu sangat tergantung pada sistem dan versi, pada jumlah dan ukuran argumen dan pada jumlah dan ukuran nama variabel lingkungan.
Secara tradisional pada Unix, batas (seperti yang dilaporkan oleh
getconf ARG_MAX
) lebih atau kurang pada ukuran kumulatif:'\0'
)'\0'
), string lingkungan sedang dengan sesuatu seperti konvensivar=value
.Mengingat yang
cp
juga dianggap sebagai argumen (adalah argumen pertama).Di Linux, itu tergantung pada versinya. Perilaku di sana berubah baru-baru ini di mana itu bukan lagi ruang tetap.
Memeriksa di Linux 3.11,
getconf ARG_MAX
sekarang melaporkan seperempat dari batas yang ditetapkan pada ukuran stack, atau 128kiB jika itu kurang dari 512kiB).(
zsh
sintaksis di bawah):Batas itu adalah pada ukuran kumulatif argumen dan string lingkungan dan beberapa overhead (saya menduga karena pertimbangan penyelarasan pada batas halaman). Ukuran pointer tidak diperhitungkan.
Mencari batas, saya dapatkan:
Ukuran kumulatif maksimum sebelum melanggar dalam hal itu adalah:
Sekarang, itu tidak berarti bahwa Anda dapat melewati 1 juta argumen kosong. Pada sistem 64 bit, 1 juta argumen kosong membuat daftar penunjuk 8MB, yang akan berada di atas ukuran tumpukan 4MiB.
(Anda akan melihat itu bukan kesalahan E2BIG. Saya tidak yakin pada titik mana proses tersebut terbunuh di sana, apakah itu ada dalam
execve
panggilan sistem atau yang lebih baru).Perhatikan juga (masih di Linux 3.11) bahwa ukuran maksimum argumen tunggal atau string lingkungan adalah 128kiB, terlepas dari ukuran stack.
sumber
164686
angka? yaitu bagaimana Anda menghitung urutan itu akan berada di bawah2097152
ukuran ARG_MAX?Itu akan tergantung pada nilai ARG_MAX yang dapat berubah antar sistem. Untuk mengetahui nilai untuk menjalankan sistem Anda (menunjukkan hasil pada tambang sebagai contoh):
Ini tidak ada hubungannya dengan
cp
atau shell Anda, itu adalah batas yang ditentukan oleh kernel, itu tidak akan menjalankan (exec()
) perintah jika argumen mereka lebih panjang dariARG_MAX
. Jadi, jika panjang daftar argumen yang Anda berikancp
lebih besar dari ARG_MAX,cp
perintah tidak akan berjalan sama sekali.Untuk menjawab pertanyaan utama Anda, maka tidak
cp
akan memproses file karena tidak akan pernah dieksekusi dengan banyak argumen. Saya juga harus menyebutkan bahwa ini tidak tergantung pada jumlah argumen tetapi pada panjangnya. Anda mungkin bisa memiliki masalah yang sama dengan nama file yang sangat sedikit tetapi sangat panjang.Cara mengatasi kesalahan ini adalah dengan menjalankan perintah Anda dalam satu lingkaran:
sumber
C
dapat memiliki masalah dengan ARG_MAX dan nama file yang sangat panjang?