Tôi thấy rằng điều này sẽ gây ra lỗi "đối số quá dài":
ls *.*
Và điều này sẽ không nâng cao nó:
for file in *.*
do
echo $file
done
Tại sao?
Tôi thấy rằng điều này sẽ gây ra lỗi "đối số quá dài":
ls *.*
Và điều này sẽ không nâng cao nó:
for file in *.*
do
echo $file
done
Tại sao?
Câu trả lời:
Đối số trên mạng quá dài Lỗi lỗi được E2BIGđưa ra bởi lệnh execvegọi hệ thống nếu tổng kích thước của các đối số (cộng với môi trường, trên một số hệ thống) quá lớn. Cuộc execvegọi này là cuộc gọi bắt đầu các quy trình bên ngoài, cụ thể tải một tệp thực thi khác (có một cuộc gọi khác fork, để chạy một quy trình riêng có mã vẫn từ cùng một tệp thực thi). Các forvòng lặp là một cấu trúc vỏ nội bộ, vì vậy nó không liên quan đến gọi execve. Lệnh ls *.*tăng lỗi không phải khi toàn cầu được mở rộng mà lslà khi được gọi.
execvekhông thành công với lỗi E2BIGkhi tổng kích thước của các đối số cho lệnh lớn hơn ARG_MAX giới hạn . Bạn có thể thấy giá trị của giới hạn này trên hệ thống của bạn bằng lệnh getconf ARG_MAX. (Có thể là bạn có thể vượt quá giới hạn này nếu bạn có đủ bộ nhớ; giữ dưới sự ARG_MAXđảm bảo execvesẽ hoạt động miễn là không xảy ra lỗi không liên quan.)
execveGiới hạn được thực thi bởi kernel, nó đặt giới hạn vì các đối số cần được sao chép qua bộ nhớ kernel tại một điểm và các quy trình người dùng không thể được phép yêu cầu số lượng bộ nhớ shell tùy ý. Bên trong lớp vỏ, không có lý do gì để có bất kỳ giới hạn nào, bất cứ điều gì phù hợp với bộ nhớ ảo đều ổn.
Tôi giả sử rằng trong ví dụ đầu tiên lsđược thực hiện bashthông qua một cuộc gọi hệ thống fork/ execcặp, trong ví dụ thứ hai, tất cả các công việc là nội bộ bash.
Cuộc execgọi có giới hạn, bashthay vào đó , công việc nội bộ không có (hoặc tốt hơn, có các giới hạn khác nhau không liên quan gì exec, có lẽ là dung lượng bộ nhớ khả dụng).
exectrong /usr/include/linux/limits.hthường, định nghĩa là ARG_MAX.
Bởi vì trong trường hợp của lsnó là một đối số và số lượng đối số bị hạn chế.
Trong trường hợp của forchu kỳ, nó chỉ là một danh sách các mục. Không có giới hạn (theo như tôi biết) cho điều đó.
for i in {00000001..20000000} ;do ((10#$i==1)) && break; done
/bin/bashso với/bin/sh(mà có lẽ là một liên kết đến dash)?