Về câu hỏi của bạn:
Trong trang người đàn ông nó nói execvp
thay thế hình ảnh của hình ảnh quá trình với cái mới. Tuy nhiên ở đây tôi đang chạy một lệnh không phải là thực thi.
Thời gian dài trước đây trình bao rất hạn chế và hầu hết tất cả các lệnh UNIX là các tệp thực thi độc lập. Bây giờ, chủ yếu cho mục đích tốc độ một số tập hợp con của lệnh UNIX được thực hiện bên trong vỏ chính nó, những lệnh được gọi là builtins
. Bạn có thể kiểm tra bất cứ lệnh được thực hiện trong vỏ của bạn như built-in hoặc không qua type
lệnh:
λ ~/ type echo
echo is a shell builtin
(. Danh mục đầy đủ các lệnh nội trú với mô tả có thể được tìm thấy trong man
trang để shell của bạn ví dụ như man bash-builtins
hoặc man builtin
)
Nhưng vẫn hầu hết các lệnh vẫn có họ thi hành được đối tác:
λ ~/ whereis echo
/bin/echo
Vì vậy, trong trường hợp cụ thể của bạn khi bạn đang chạy:
char* arg[] = {"ls", "-l", NULL};
execvp(arg[0],arg);
Bạn đang thực sự thay thế không gian địa chỉ của quy trình hiện tại bằng không gian địa chỉ (rất có thể) /bin/ls
.
trực giác của tôi là tôi phải đọc các tập tin và có thể được phân tích nó để lưu trữ các đối số trong arg.
Thực tế là bạn có. Nhưng bạn cũng có thể sử dụng một số chức năng trong hạt nhân cho rằng aka "công việc":
Thay vì đặt tên tập tin trong tập tin riêng biệt add cái gọi là công việc như dòng đầu tiên của tập tin bạn muốn mèo:
#!/bin/cat
Và thêm chmod +x
vào đó. Sau đó, bạn có thể chạy nó như là thực thi (thông qua bất kỳ exec
chức năng hoặc vỏ):
λ ~/tmp/ printf '#!/bin/cat\nTEST\n' > cat_me
λ ~/tmp/ chmod +x cat_me
λ ~/tmp/ ./cat_me
#!/bin/cat
TEST
Trong số nguyên nhân đó là có một nhược điểm của in shebang
tự với tập tin nhưng nó vẫn còn vui vẻ để làm điều đó trong-kernel =)
BTW. Vấn đề mà bạn mô tả nếu quá phổ biến rằng có một tập tin thực thi đặc biệt gọi là xargs
mà (trong lời giải thích rất đơn giản) thực thi chương trình được đưa ra trong danh sách các đối số được truyền qua stdin. Để biết thêm thông tin, hãy tham khảo man xargs
.
Đối ghi nhớ dễ dàng exec
-family Tôi thường sử dụng bảng sau:
Figure 8.14. Differences among the six exec functions
+----------+----------+----------+----------+--------+---------+--------+
| Function | pathname | filename | agr list | argv[] | environ | envp[] |
+----------+----------+----------+----------+--------+---------+--------+
| execl | * | | * | | * | |
+----------+----------+----------+----------+--------+---------+--------+
| execlp | | * | * | | * | |
+----------+----------+----------+----------+--------+---------+--------+
| execle | * | | * | | | * |
+----------+----------+----------+----------+--------+---------+--------+
| execv | * | | | * | * | |
+----------+----------+----------+----------+--------+---------+--------+
| execvp | | * | | * | * | |
+----------+----------+----------+----------+--------+---------+--------+
| execve | * | | | * | | * |
+----------+----------+----------+----------+--------+---------+--------+
| letter | | p | l | v | | e |
+----------+----------+----------+----------+--------+---------+--------+
Vì vậy, trong trường hợp của bạn execvp
mất filename, argv (v) và environ (e). Sau đó, nó cố gắng "đoán" tên đường dẫn (còn gọi là đường dẫn đầy đủ) bằng cách thêm filename
(trong trường hợp của bạn cat
) vào từng thành phần đường dẫn trong PATH
cho đến khi tìm đường dẫn có thể thực thi filename
.
Thông tin chi tiết hơn về những gì đang diễn ra dưới mui xe của exec
(bao gồm cả nội dung thừa kế) có thể được tìm thấy trong Advanced Programming in the UNIX Environment (2nd Edition) by W. Richard Stevens and Stephen A. Rago aka APUE2.
Nếu bạn quan tâm đến UNIX internals bạn có lẽ nên đọc nó.
Tất cả các lệnh trong linux đều có thể thực thi được. – Alex
Nhập 'ls' vào thiết bị đầu cuối của bạn để xem vị trí của chương trình' ls'. Bạn thực sự đang chạy một tệp thực thi khi bạn nói 'ls'. – Cornstalks
@Alex: Ngoại trừ một số lệnh đặc biệt được triển khai trong trình bao, như 'cd',' source' và 'exit'. – duskwuff