簡體   English   中英

像“ls -l”這樣的命令不在execl中執行,而在execvp中它可以工作

[英]Commands like “ls -l” not executing in execl, whereas in execvp it works

execl變體中使用下面的代碼, ls可以工作,但ls -l不起作用,但在我的execvp方法中lsls-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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM