Một vỏ tương tác có thể trở thành không tương tác hoặc ngược lại?
Lưu ý: Tôi đã thực hiện rất nhiều nghiên cứu về câu hỏi cơ bản, "Sự khác biệt giữa tương tác và không tương tác là gì?", Và kết quả nghiên cứu của tôi đã khiến tôi đặt câu hỏi này .
Câu hỏi này có phần mở đầu dài một phần vì nó rất quan trọng loại định nghĩa chúng ta sử dụng cho "tương tác" để trả lời nó. Một định nghĩa có thể là một nhãn tùy ý cho một bộ nhất định; nó có thể được mô tả của các thuộc tính khác nhau; hoặc nó có thể cung cấp cho bạn thông tin bạn có thể sử dụng để dự đoán hành vi và hiểu mục đích. Loại cuối cùng này chúng ta có thể gọi là "định nghĩa hành động" hoặc "định nghĩa động" và nó là hữu ích nhất.
Trong man 1p sh
, định nghĩa sau đây của một vỏ tương tác được đưa ra:
If the -i option is present, or if there are no operands and the shell’s standard input and standard error are attached to a terminal, the shell is considered to be interactive.
Từ việc đề cập đến "tùy chọn -i" và sử dụng từ "toán hạng", điều này đề cập đến lời gọi của shell , không phải các thuộc tính có thể được kiểm tra trong shell đang chạy.
Trang người đàn ông Bash diễn đạt nó một chút khác biệt:
An interactive shell is one started without non-option arguments and without the -c option whose standard input and error are both connected to terminals (as determined by isatty(3)), or one started with the -i option. PS1 is set and $- includes i if bash is interactive, allowing a shell script or a startup file to test this state.
Định nghĩa trong câu đầu tiên một lần nữa chỉ đề cập đến sự bắt đầu của một vỏ.
Câu thứ hai (trong bài đọc của tôi) định nghĩa các điều kiện được sử dụng làm proxy để xác định xem shell có được bắt đầu theo những cách cụ thể được xác định là làm cho nó "tương tác" hay không.
Lưu ý rằng tôi không diễn giải câu này là: "Một bash shell là tương tác khi và chỉ khi $-
bao gồm 'i'." $-
dường như chỉ là một chỉ báo tiện dụng, không phải là một định nghĩa về tương tác. Điều này có liên quan chủ yếu đến câu hỏi của tôi.
Cả hai điều này ( sh
định nghĩa POSIX và Bash) là các định nghĩa cơ học cho biết trong trường hợp nào nhãn "tương tác" áp dụng cho vỏ bạn đã bắt đầu. Họ không định nghĩa hành động vì họ không đưa ra bất kỳ ý nghĩa nào của nhãn này.
Tuy nhiên, tôi thấy rằng trong suốt phần còn lại của trang Bash man được rắc các tham chiếu đến shell hoạt động theo một số cách nhất định "trừ khi đó là shell tương tác" hoặc "chỉ trong các shell tương tác, hoặc nếu tùy chọn _____ được đặt." (Có rất nhiều ví dụ và đó không phải là điểm chính của câu hỏi này.)
Vì vậy, tôi sẽ chấp nhận rằng "tương tác" chỉ là một nhãn tiện lợi cho bộ sưu tập các hành vi "tương tác" mặc định (cài đặt tùy chọn) được mô tả trong suốt phần còn lại của trang man. Bản thân nó không phải là một thuật ngữ hoặc đối tượng cơ bản; nó không có định nghĩa chính thức bên ngoài mã nguồn của shell. (Không giống như, ví dụ, các thuật ngữ "mô tả tệp mở" hoặc "quá trình dừng" dùng để chỉ các khái niệm trừu tượng được xây dựng trong thiết kế của chính kernel.)
(Mặc dù cũng được định nghĩa trong định nghĩa POSIX sh
, nhưng trang người đàn ông đó [ man 1p sh
] sử dụng ít hơn "trừ khi vỏ tương tác" và các câu lệnh tương tự như vậy man bash
, và hầu như chỉ tập trung vào sự khác biệt về thời gian gọi, vì vậy tôi sẽ tập trung vào Bash từ thời điểm này trở đi.)
Dù sao, một số hàm ý của shell là "tương tác" chỉ có liên quan tại thời điểm gọi , chẳng hạn như các tệp được lấy bởi shell trước khi nó đọc các lệnh khác. Tuy nhiên, có những hàm ý (ít nhất là trong Bash) có liên quan bất cứ lúc nào. Do đó, phải có một cách để nói, đối với bất kỳ shell đang chạy nào , cho dù nó có tương tác hay không.
Chạy set +i
trong lớp vỏ Bash tương tác khiến 'i' bị xóa khỏi nội dung của $-
.
Câu hỏi là: Điều này thực sự có nghĩa là vỏ không còn tương tác?
Theo định nghĩa chính xác của Bash, không nên, vì không nơi nào trong định nghĩa được yêu cầu rằng 'tôi' phải có mặt trong $-
:
An interactive shell is one started without non-option arguments and without the -c option whose standard input and error are both connected to terminals (as determined by isatty(3)), or one started with the -i option.
Việc đọc chính xác định nghĩa chính xác cũng đặt ra câu hỏi: Nếu stdin hoặc stderr của thiết bị đầu cuối tương tác được chuyển hướng để chúng không còn được kết nối với thiết bị đầu cuối, vỏ có trở thành không tương tác không?
(Dường như câu trả lời cho câu hỏi này là "không" và trang man có thể bao gồm công cụ sửa đổi: "có đầu vào và lỗi tiêu chuẩn đều được kết nối với thiết bị đầu cuối ... tại thời điểm gọi " , nhưng tôi không biết dứt khoát.)
Nếu câu trả lời là: "Không, một lớp vỏ có thể không trở thành không tương tác, cũng không phải ngược lại", sau đó là những gì dứt khoát cách để xác định nếu vỏ là tương tác?
Đặt một cách khác: Nếu có những hành vi của một "vỏ tương tác" tồn tại sau đó set +i
, thì điều gì được sử dụng để xác định rằng những hành vi đó nên tiếp tục áp dụng?
Bất cứ ai cũng nghi ngờ điều đó: Có những hành vi của một cái vỏ được gọi một cách tương tác mà tồn tại sau đó set +i
và những hành vi của một cái vỏ được gọi không tương tác mà tồn tại sau đó set -i
. Ví dụ, xem xét đoạn trích sau từ man bash
:
COMMENTS In a non-interactive shell, or an interactive shell in which the inter- active_comments option to the shopt builtin is enabled (see SHELL BUILTIN COMMANDS below), a word beginning with # causes that word and all remaining characters on that line to be ignored. An interactive shell without the interactive_comments option enabled does not allow comments. The interactive_comments option is on by default in interac- tive shells.
Do đó, bằng cách bỏ đặt interactive_comments
tùy chọn, chúng ta có thể thấy sự khác biệt giữa các vỏ tương tác và không tương tác. Sự tồn tại của sự khác biệt này được thể hiện bằng kịch bản sau:
#!/bin/bash
# When the testfile is run interactively,
# all three comments will produce an error
# (even the third where 'i' is not in '$-').
# When run noninteractively, NO comment will
# produce an error, though the second comment
# is run while 'i' IS in '$-'.
cat >testfile <<'EOF'
shopt interactive_comments
shopt -u interactive_comments
shopt interactive_comments
echo $-
#first test comment
set -i
echo $-
#second test comment
set +i
echo $-
#third test comment
EOF
echo 'running bash -i <testfile'
bash -i <testfile
echo 'running bash <testfile'
bash <testfile
Điều này xác nhận rằng "tương tác" và "có i
giá trị $-
" không tương đương.
Một thử nghiệm tương tự sử dụng ${parameter:?word}
với tham số unset tạo ra kết quả tương tự, một lần nữa xác nhận rằng đó $-
không phải là "nguồn sự thật" cho tính tương tác của vỏ.
Vì vậy, cuối cùng, đặc điểm 'tương tác' dứt khoát của vỏ được lưu trữ ở đâu?
Và, một vỏ tương tác có thể trở thành không tương tác hoặc ngược lại? (... Bằng cách thay đổi đặc điểm này?)