execlp с поиском в качестве параметра

Я попытаюсь объяснить свою проблему. Если я выполню следующую команду

find ~ -name file.txt

в Linux все файлы с именем file.txt будут отображаться на экране консоли. Я хочу написать программу на C, которая будет делать то же самое, используя функцию execlp для поиска всех файлов с определенным именем, например file.txt.

Если я сделаю что-то вроде этого:

execlp("find","find","-name","file.txt",NULL); 

компилируется нормально, но при выполнении показывает только файл с именем file.txt, который находится в текущем рабочем каталоге. Если я сделаю что-то подобное в своей программе:

execlp("find","find","~","-name","file.txt"); 

компилируется нормально, но при выполнении выдает следующую ошибку:

find: `~': No such file or directory. 

Какие параметры я должен указать функции execlp для поиска file.txt во всех доступных каталогах? Мне нужно сделать это с помощью функции execlp. Большое спасибо!


person Zan    schedule 21.10.2013    source источник
comment
Ваша оболочка расширяет ~ из строки cmd, но не в вызове execlp. Используйте полный путь или укажите элемент каталога, который действительно существует (на ум приходит .).   -  person WhozCraig    schedule 21.10.2013
comment
Дело в том, что эта программа должна работать для разных учетных записей пользователей. Например, если мой друг запускает эту программу на своей учетной записи, он должен получить все файлы с именем file.txt, которые существуют в его файловой системе. Пользователь не имеет прав доступа к файлам других пользователей.   -  person Zan    schedule 21.10.2013


Ответы (1)


«~» в вашем первом примере расширяется оболочкой, а не ядром. При выполнении команды на C вы не проходите через оболочку, поэтому вы не можете ожидать, что такая замена произойдет для вас. Ну, если вы действительно не вызовете оболочку и не попросите ее выполнить вашу команду, как в execlp("/bin/sh", "/bin/sh", "-c", "find", "~", ...);.

Предпочтительный способ выполнить то, что вы делаете, — проверить переменную среды HOME или получить домашний каталог для текущего пользователя из базы данных паролей. Вот как это сделать.

#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
#include <stdlib.h>

const char *homedir = getenv("HOME");
if (homedir == NULL) {
    struct passwd *pw = getpwuid(getuid());
    homedir = pw->pw_dir;
}

Затем просто замените аргумент «~» в вашем коде на переменную homedir.

person jwatkins    schedule 21.10.2013
comment
Спасибо, чувак, это работает просто отлично. И спасибо всем за вашу помощь. - person Zan; 21.10.2013
comment
Я обновил свой код, чтобы сначала проверить переменную среды HOME в соответствии с рекомендацией man-страницы getpwuid. Это то, что ~ в bash сделает. Это сделано для того, чтобы пользователь мог переопределить свой собственный домашний каталог. Однако обратите внимание, что полагаться на переменную окружения HOME может быть неуместно, если вам нужен авторитетный ответ (то есть, если разрешение пользователю изменять свой домашний каталог может привести к проблемам с безопасностью. - person jwatkins; 21.10.2013