execlp с find като параметър

Ще се опитам да обясня проблема си. Ако изпълня следната команда

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, според препоръката на страницата с ръководство на getpwuid. Това би направил ~ в bash. Това се прави, за да позволи на потребителя да предефинира собствената си домашна директория. Обърнете внимание обаче, че разчитането на променливата на обкръжението HOME може да е неподходящо, ако имате нужда от достоверен отговор (тоест, ако позволяването на потребителя да променя домашната си директория може да доведе до проблем със сигурността. - person jwatkins; 21.10.2013