Tôi đang chuyển một biến cho một tập lệnh trên dòng lệnh. Giới hạn ký tự của một lệnh là gì? ví dụ:
$ MyScript reallyreallyreally...reallyreallyreallylongoption
Cảm ơn.
Tôi đang chuyển một biến cho một tập lệnh trên dòng lệnh. Giới hạn ký tự của một lệnh là gì? ví dụ:
$ MyScript reallyreallyreally...reallyreallyreallylongoption
Cảm ơn.
Câu trả lời:
Giới hạn áp đặt shell / OS thường rất dài - thường là một hoặc hai trăm nghìn ký tự.
getconf ARG_MAX
sẽ cung cấp cho bạn giới hạn đầu vào tối đa cho một lệnh. Trên hệ thống Debian hiện tại tôi có một thiết bị đầu cuối mở trên này trả về 131072 là 128 * 1024. Giới hạn được giảm bởi các biến môi trường của bạn như thể bộ nhớ của tôi phục vụ cho tôi một cách chính xác, chúng được truyền trong cùng một cấu trúc bởi vỏ, mặc dù điều đó sẽ chỉ mất vài trăm ký tự trong hầu hết các trường hợp. Để tìm một xấp xỉ của giá trị này chạy env | wc -c
- điều này gợi ý 325 ký tự tại thời điểm hiện tại trên thông tin đăng nhập này trên máy này.
Các tập lệnh có khả năng cho phép toàn bộ chiều dài này, nhưng không có khả năng các tiện ích khác sẽ áp đặt các giới hạn của chính chúng hoặc cố ý hoặc thông qua các vấn đề thiết kế. Cũng có thể có các giới hạn nhân tạo về thời gian một đối số riêng lẻ trên một dòng lệnh dài có thể và / hoặc một đường dẫn đến một tệp có thể dài bao lâu.
getconf ARG_MAX
cung cấp 2097152, nhưng độ dài tối đa tôi có thể vượt qua vẫn là 131071 (và tôi không phải khấu trừ kích thước của môi trường).
xargs
và thậm chí find -exec
là bạn bè của bạn khi xử lý các danh sách đối số khổng lồ.
getconf
là mức kernel tôi nghĩ. Có lẽ bash đang đặt giới hạn thấp hơn bởi thiết kế / cấu hình của nó? Ngoài ra, kiến thức của tôi về điều này xuất phát từ một thời gian trước đây nên có thể mọi thứ đã thay đổi một chút gần đây, mặc dù đó không phải là một lĩnh vực mà tôi mong đợi sẽ thấy rất nhiều chuyển động ngoại trừ trong các vỏ thử nghiệm mới.
ksh
, zsh
, dash
, fish
và Bash 3 như tôi đã làm trong Bash 4. Các thông báo lỗi từ fish
có thể cung cấp thông tin: "cá: Tổng kích thước của danh sách đối số và môi trường (130kB) vượt quá giới hạn hệ điều hành của 2.0MB . " Tuy nhiên, set | wc -c
là 306317 và env | wc -c
là 2507 không tính đến sự khác biệt. Tôi không biết những gì khác đang được tính.
ARG_MAX thực sự giới hạn tổng kích thước của dòng lệnh và môi trường, nhưng bạn đang phải đối mặt với một giới hạn bổ sung: một đối số không được dài hơn MAX_ARG_STRLEN (không may được mã hóa cứng là 131072).
Bạn có nghĩa là chiều dài biến dài nhất là gì? Để tìm ra điều đó, bạn có thể sử dụng "x" của perl để tạo một tên biến rất dài:
VAR=`perl -e 'print "a"x131071'` ; bash a.sh $VAR
Trên hệ thống của tôi 131071 hoạt động:
và biến được in ở 131072, nó quá lớn:
VAR=`perl -e 'print "a"x131072'` ; bash a.sh $VAR
bash: /bin/bash: Argument list too long
perl
và tập lệnh:/bin/echo "$(printf "%*s" 131071 ".")">/dev/null
printf '%s\n' "$(printf '%*s' 131072 .)" >/dev/null
hoạt động.
printf
một vỏ được tích hợp sẵn, do bash
đó không cần phải thực hiện một exec()
quá trình khác. ARG_MAX
chỉ quan trọng đối với chiều dài của danh sách đối số của exec
hàm ( exec()
, execl()
, execlp()
, execvp()
, execvpe()
, vv).