Apakah ada semacam batasan karakter yang diberlakukan di bash (atau shell lain) untuk berapa lama input bisa? Jika ya, berapa batas karakter itu?
Yaitu Apakah mungkin untuk menulis perintah di bash yang terlalu panjang untuk dieksekusi oleh baris perintah? Jika tidak ada batasan yang disyaratkan, apakah ada batasan yang disarankan?
bash
shell
unix
command-line-arguments
Derek Halden
sumber
sumber
Jawaban:
Batas panjang baris perintah tidak ditentukan oleh shell, tetapi oleh sistem operasi. Batasan ini biasanya dalam kisaran ratusan kilobyte. POSIX menunjukkan batas ini
ARG_MAX
dan pada sistem konforman POSIX Anda dapat menanyakannya$ getconf ARG_MAX # Get argument limit in bytes
Misalnya pada Cygwin ini adalah 32000, dan pada sistem BSD dan Linux yang berbeda saya menggunakannya antara 131072 sampai 2621440.
Jika Anda perlu memproses daftar file yang melebihi batas ini, Anda mungkin ingin melihat
xargs
utilitas, yang memanggil program berulang kali dengan subset argumen tidak melebihiARG_MAX
.Untuk menjawab pertanyaan spesifik Anda, ya, adalah mungkin untuk mencoba menjalankan perintah dengan daftar argumen yang terlalu panjang. Shell akan error dengan pesan bersama "daftar argumen terlalu panjang".
Perhatikan bahwa input ke program (seperti yang dibaca di stdin atau deskriptor file lainnya) tidak dibatasi (hanya oleh resource program yang tersedia). Jadi, jika skrip shell Anda membaca string menjadi variabel, Anda tidak dibatasi oleh
ARG_MAX
. Pembatasan juga tidak berlaku untuk shell-builtins.sumber
cmd <<< "$LONG_VAR"
dan nilai LONG_VAR melebihi batas, apakah perintah saya akan meledak?LONG_VAR
dikirimkan pada stdin - dan itu dilakukan seluruhnya di shell; itu tidak diperluas sebagai argumen untukcmd
, sehingga batas ARG_MAX untuk fork () / exec () tidak ikut bermain. Sangat mudah untuk mencoba sendiri: buat variabel dengan konten yang melebihi ARG_MAX dan jalankan perintah Anda.blah="$(cat /home/schwager/Music/Recordings/20090420\ 131623.m4a)"; cat <<< $blah >/dev/null
. Perhatikan tidak ada kesalahan.xargs
di MacOS 10.12.6 batas berapa banyak ia mencoba untuk dimasukkan ke dalam satuexec()
untukARG_MAX - 4096
. Jadi penggunaan skripxargs
mungkin berhasil, sampai suatu hari ketika seseorang menempatkan terlalu banyak barang di lingkungan. Mengalami ini sekarang (atasi denganxargs -s ???
:).Oke, Warga. Jadi saya telah menerima batas panjang baris perintah sebagai Injil untuk beberapa waktu. Lantas, apa hubungannya dengan asumsi seseorang? Tentu- periksa mereka.
Saya memiliki mesin Fedora 22 yang dapat saya gunakan (artinya: Linux dengan bash4). Saya telah membuat direktori dengan 500.000 inode (file) di dalamnya masing-masing sepanjang 18 karakter. Panjang baris perintah adalah 9.500.000 karakter. Dibuat demikian:
seq 1 500000 | while read digit; do touch $(printf "abigfilename%06d\n" $digit); done
Dan kami mencatat:
Catat bagaimanapun saya dapat melakukan ini:
$ echo * > /dev/null
Tapi ini gagal:
$ /bin/echo * > /dev/null bash: /bin/echo: Argument list too long
Saya bisa menjalankan for loop:
$ for f in *; do :; done
yang merupakan shell builtin lain.
Membaca dokumentasi
ARG_MAX
dengan cermat untuk status, Panjang maksimum argumen ke fungsi exec . Artinya: Tanpa meneleponexec
, tidak adaARG_MAX
batasan. Jadi itu akan menjelaskan mengapa bawaan shell tidak dibatasi olehARG_MAX
.Dan memang, saya dapat
ls
direktori saya jika daftar argumen saya adalah 109948 file, atau sekitar 2.089.000 karakter (memberi atau menerima). Setelah saya menambahkan satu lagi file nama file 18 karakter, maka saya mendapatkan kesalahan daftar Argument terlalu panjang . BegituARG_MAX
juga bekerja seperti yang diiklankan: exec gagal dengan lebih dariARG_MAX
karakter pada daftar argumen - termasuk, harus dicatat, data lingkungan.sumber
for f in *; do echo $f; done
tidak akan bercabang sama sekali (semua bawaan). Jadi saya tidak tahu bahwa kombo find-xargs akan lebih cepat; itu belum diuji. Memang, saya tidak tahu apa set masalah OP itu. Mungkinfind /path/to/directory
tidak akan berguna baginya karena itu akan mengembalikan nama path file. Mungkin dia menyukai kesederhanaan sebuahfor f in *
lingkaran. Terlepas dari itu, percakapannya adalah tentang batas input jalur - bukan efisiensi. Jadi mari kita tetap pada topik, yang berkaitan dengan panjang baris perintah.Ada batas buffer seperti 1024. Pembacaan hanya akan menggantung di pertengahan paste atau masukan. Untuk mengatasi ini gunakan opsi -e.
http://linuxcommand.org/lc3_man_pages/readh.html
-e menggunakan Readline untuk mendapatkan baris dalam shell interaktif
Ubah bacaan Anda menjadi baca -e dan masukan baris yang mengganggu akan hilang.
sumber
read
: "Yaitu apakah mungkin untuk menulis perintah di bash yang terlalu panjang untuk dieksekusi oleh baris perintah?"bash --noediting
, dan pada prompt baru coba jalankan perintahecho somereallylongword
, di mana beberapa kata panjang biasanya lebih dari 4090 karakter. Mencoba di Ubuntu 18.04, kata itu terpotong, jadi jelas itu ada hubungannya dengan Readline tidak diaktifkan.