Một kịch bản tương tự, không có sudo
, nhưng kết quả tương tự:
$ cat script.sh
#!/bin/bash
sed -e 's/^/--/'
whoami
$ bash < script.sh
--whoami
$ dash < script.sh
itvirta
Với bash
, phần còn lại của tập lệnh là đầu vào sed
, với dash
, shell diễn giải nó.
Chạy strace
trên những cái đó: dash
đọc một khối kịch bản (tám kB ở đây, quá đủ để giữ toàn bộ tập lệnh), và sau đó sinh ra sed
:
read(0, "#!/bin/bash\nsed -e 's/^/--/'\nwho"..., 8192) = 36
stat("/bin/sed", {st_mode=S_IFREG|0755, st_size=73416, ...}) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|...
Điều đó có nghĩa là tập tin nằm ở cuối tập tin và sed
sẽ không thấy bất kỳ đầu vào nào. Phần còn lại được đệm trong dash
. (Nếu tập lệnh dài hơn kích thước khối 8 kB, phần còn lại sẽ được đọc bởi sed
.)
Bash, mặt khác, tìm kiếm trở lại đến cuối của lệnh cuối cùng:
read(0, "#!/bin/bash\nsed -e 's/^/--/'\nwho"..., 36) = 36
stat("/bin/sed", {st_mode=S_IFREG|0755, st_size=73416, ...}) = 0
...
lseek(0, -7, SEEK_CUR) = 29
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|...
Nếu đầu vào đến từ một đường ống, như ở đây:
$ cat script.sh | bash
tua lại không thể được thực hiện, vì đường ống và ổ cắm không thể tìm kiếm. Trong trường hợp này, Bash quay lại đọc một ký tự đầu vào tại một thời điểm để tránh đọc quá nhiều. ( fd_to_buffered_stream()
ininput.c
) Thực hiện một cuộc gọi hệ thống đầy đủ cho mỗi byte về nguyên tắc không hiệu quả lắm. Trong thực tế, tôi không nghĩ rằng các lần đọc sẽ là một chi phí lớn so với thực tế là hầu hết mọi thứ mà trình bao gồm liên quan đến việc sinh ra toàn bộ các quy trình mới.
Một tình huống tương tự là thế này:
echo -e 'foo\nbar\ndoo' | bash -c 'read a; head -1'
Subshell phải đảm bảo read
chỉ đọc lên dòng mới đầu tiên, để head
thấy dòng tiếp theo. (Điều này cũng hoạt động với dash
.)
Nói cách khác, Bash đi đến các độ dài bổ sung để hỗ trợ đọc cùng một nguồn cho chính tập lệnh và cho các lệnh được thực thi từ nó. dash
không. Cái zsh
và ksh93
được đóng gói trong Debian đi cùng với Bash về điều này.
sudo su
: unix.stackexchange.com/questions/218169/ Khăn