[英]Execvp works with "ls -l | wc" and failed with "ls -l|wc
[英]Commands like “ls -l” not executing in execl, whereas in execvp it works
在execl
變體中使用下面的代碼, ls
可以工作,但ls -l
不起作用,但在我的execvp
方法中ls
和ls-l
工作。 我采用execl
方法的原因是因為二進制文件的路徑可能不同而execvp
沒有為我提供該功能。 理想情況下,我希望execl
也可以在ls -l
上工作,但是現在它不適用於ls -l
。 我試過閱讀手冊頁,但沒有幫助。
void child(int argc, char *argv[MAX_ARGS])
{
execvp(argv[0], argv);
}
void child(char *argv[], char* path)
{
execl(path, argv, NULL);
}
使用execl()
,您必須逐個列出參數; 它只有在您確切知道要提前執行的內容時才有用:
execl("/bin/ls", "ls", "-l", (char *)0);
execl("/bin/sh", "sh", "-c", "ls -l", (char *)0);
execl("/bin/ls", "pink elephants", "-l", (char *)0);
等等。
如果您不知道需要處理多少個參數,請使用execvp()
或execv*()
系列的其他成員之一。 另請注意,您必須指定命令的路徑; execvp()
搜索$PATH
,但execl()
沒有。 另請注意,您可以選擇傳遞為argv[0]
的值。
我采用
execl()
方法的原因是因為二進制文件的路徑可能不同而execvp()
沒有為我提供該功能。
我不確定你的意思。 使用execvp()
,您可以指定:
char *argv[] = { "ls", "-l", 0 };
execvp(argv[0], argv);
execv("/bin/ls", argv);
execvp()
將在$PATH
上搜索ls
並執行匹配的第一個程序。 第二個將執行/bin/ls
而不查看$PATH
。
char *argv[] = { "/bin/ls", "-l", 0 };
execv(argv[0], argv);
execvp(argv[0], argv);
這些都可以起作用; 第二個不會使用基於PATH的搜索,因為可執行文件名( argv[0]
)包含斜杠。
令我困惑的是
execvp(argv[0], argv);
為什么我們將整個argv
作為第二個參數傳遞? 所以假設argv[0]
是"ls -l"
,為什么我們必須將整個argv
作為第二個參數傳遞?
假設argv[0]
包含"ls -l"
,則表示存在問題。 大多數系統沒有文件“ /bin/ls -l
”或“ /usr/bin/ls -l
”(其中空白是名稱的一部分),但這就是您要執行的內容。
exec*()
函數是執行進程的低級函數。 第一個參數指定要運行的程序(通常是二進制;有時是一個帶有shebang行的腳本,例如#!/bin/sh
作為第一行)。 在execv()
或execvp()
或execve()
或execvpe()
,第二個參數是參數的向量,就像main()
函數接收參數向量(或參數向量,因此argv
)一樣。 這是程序參數的以null結尾的列表。 如果要使用選項-l
執行ls
命令,則需要在argv
指定三個(!)值"ls"
, "-l"
和空指針:
char argv[] = { "ls", "-l", 0 };
使用execl*()
函數,指定要作為第一個參數運行的程序,然后寫出參數向量:
execl("/bin/ls", "ls", "-l", (char *)0);
如果你有10個參數,你必須寫出10個參數(加上空指針)。
在exec*()
函數中,名稱包含:
l
- 列表格式參數 v
- 矢量格式參數 p
- 對程序執行PATH查找(如果給定名稱不包含斜杠) e
- 也采用環境變量向量 這些結合起來給出:
execl()
execv()
execlp()
execle()
execvp()
execve()
偶爾有點令人厭煩的是沒有execlpe()
和execvpe()
(但請參閱Linux擴展execvpe(3)
)。 對於man 2 exec
頁面來說,從概要中省略其中的一些也是傳統的,但在手冊頁的正文中提到它們 - 傳統/遺產可以追溯到1979年至少第7版UNIX™(並且至少持續到RHEL 5 Linux和Mac OS X 10.7.5; man 2 execl
頁面提到了execve()
但未在概要部分中列出它。 其他exec*()
函數都可以在execve()
上構建 - 這是集合中的基本函數(因此在Linux手冊中列為execve(2)
)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.