LinuxForum.Fans
Тема

Как узнать полный путь к файлу по его имени?

Автор: c-villain 31 сообщений 14166 просмотров
#134470

Есть ли в линуксе функция, которая выдает полный путь к файлу (иначе его полное имя)? аналогичная функция в винде называется GetFullPathName. Заранее спасибо=)

#134475

зависит от того, чем описывается файл. Если дескриптором, то нет и быть не может.

#134477

нет... именно коротким именем... короче по fileName получить PathName..
наиболее интересно как это делается в ядре.

#134499

locate, см. пример в "man locate".
find
Если программа или скрипт запускается в каталоге с этим файлом,
то путь к нему даст pwd.

Пётр.

#134500

так, Петр, спасибо=)
В ядре будет работать?..
мне для драйвера нужно...

#134510

locate, find и PWD - это вообще не в ту степь... всё это годится только для скриптов. ещё в тудаже readlink
для простого юзерспейса есть getcwd() - возвращает текущую рабочую директорию. Дальше можно ручками скрестить с относительным путём. (именно так поступает readlink)
для ядра - не совсем понятно, что именно за драйвер... можно например из структуры текущего процесса вытащить его текущую директорию. Ещё можно посмотреть как в glibc обрабатывается getcwd() и какой системный вызов посылается ядру.

#134594
c-villain написал:
Есть ли в линуксе функция, которая выдает полный путь к файлу (иначе его полное имя)? аналогичная функция в винде называется GetFullPathName. Заранее спасибо=)

т.е у вас есть неполный путь, а вы хотите узнать, в каком каталоге это запущенно? тогда посмотрите в нулевой переменной, которая принимается функцией main(). там записана команда, которой эта ваша программа запускалась.
Есть функция stat()

man 2 stat написал:
STAT(2) Linux Programmer's Manual STAT(2)

NAME
stat, fstat, lstat - get file status

SYNOPSIS
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int stat(const char *path, struct stat *buf);
int fstat(int fd, struct stat *buf);
int lstat(const char *path, struct stat *buf);

Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

lstat(): _BSD_SOURCE || _XOPEN_SOURCE >= 500

DESCRIPTION
These functions return information about a file. No permissions are required on the file itself, but —
in the case of stat() and lstat() — execute (search) permission is required on all of the directories in
path that lead to the file.

stat() stats the file pointed to by path and fills in buf.

lstat() is identical to stat(), except that if path is a symbolic link, then the link itself is stat-ed,
not the file that it refers to.

fstat() is identical to stat(), except that the file to be stat-ed is specified by the file descriptor
fd.
#134599

оО.... отлично, спасибо!)))
проверю... Главное, чтоб в ядре заработала...

#134606
c-villain написал:
проверю... Главное, чтоб в ядре заработала...

дык это и есть путь к ядру...
попробуйте
[console]man -k нужное[/console]
это поиск внутри манов. можно потом k большим сделать...
удачи

#134608

проверю - отпишу, вдруг интересно)))

#134609

кстати, исходники stat() гляньте. там написано, как именно обращается stat() к ядру.

#134611

оО... прекрасно... тогда должно заработать))))

#135783
drBatty написал:
[quote=c-villain]Есть ли в линуксе функция, которая выдает полный путь к файлу (иначе его полное имя)? аналогичная функция в винде называется GetFullPathName. Заранее спасибо=)

т.е у вас есть неполный путь, а вы хотите узнать, в каком каталоге это запущенно? тогда посмотрите в нулевой переменной, которая принимается функцией main(). там записана команда, которой эта ваша программа запускалась.
Есть функция stat()

man 2 stat написал:
STAT(2) Linux Programmer's Manual STAT(2)

NAME
stat, fstat, lstat - get file status

SYNOPSIS
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int stat(const char *path, struct stat *buf);
int fstat(int fd, struct stat *buf);
int lstat(const char *path, struct stat *buf);

Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

lstat(): _BSD_SOURCE || _XOPEN_SOURCE >= 500

DESCRIPTION
These functions return information about a file. No permissions are required on the file itself, but —
in the case of stat() and lstat() — execute (search) permission is required on all of the directories in
path that lead to the file.

stat() stats the file pointed to by path and fills in buf.

lstat() is identical to stat(), except that if path is a symbolic link, then the link itself is stat-ed,
not the file that it refers to.

fstat() is identical to stat(), except that the file to be stat-ed is specified by the file descriptor
fd.
[/quote]

так... только сейчас руки дошли)))
ман вывел: что эта функция вывыодит содержимое полей дескриптора файла... полного пути в структуре stat нет...
так что этот вариант отпадает((((
any ideas?
#135796
c-villain написал:
полного пути в структуре stat нет...

нет. за то есть номер инода. значит можно прочитать инод каталога "точка".

text
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <dirent.h>

int main(int argc, const char *argv[]) { printf("%s\n", argv[0]); //int stat(const char *path, struct stat *buf); //struct stat { //dev_t st_dev; /* ID of device containing file */ //ino_t st_ino; /* inode number */ //mode_t st_mode; /* protection */ //nlink_t st_nlink; /* number of hard links */ //uid_t st_uid; /* user ID of owner */ //gid_t st_gid; /* group ID of owner */ //dev_t st_rdev; /* device ID (if special file) */ //off_t st_size; /* total size, in bytes */ //blksize_t st_blksize; /* blocksize for file system I/O */ //blkcnt_t st_blocks; /* number of 512B blocks allocated */ //time_t st_atime; /* time of last access */ //time_t st_mtime; /* time of last modification */ //time_t st_ctime; /* time of last status change */ }; struct stat si; int err = stat(argv[0], &si); if(err) return err; //struct dirent *readdir(DIR *dirp); // struct dirent { // ino_t d_ino; /* inode number */ // off_t d_off; /* offset to the next dirent */ // unsigned short d_reclen; /* length of this record */ // unsigned char d_type; /* type of file; not supported by all file system types */ // char d_name[256]; /* filename */ }; DIR * dirp; struct dirent *dr; dirp = opendir("."); if(!dirp) return 67; while(dr = readdir(dirp)) { if(strcmp(dr->d_name, ".") == 0 || dr->d_ino == si.st_ino) printf("%d\t%s\n", dr->d_ino, dr->d_name); }

return 0; }

и каталога "две точки" тоже.. Так вы сможете рекурсивно распутать весь полный путь.
до корня, где как известно две точки равны одной. а вот спец-функции я не нашёл...

#135802

ВАЖНО!

есть ДВЕ readdir:

man 2 readdir написал:
DESCRIPTION
This is not the function you are interested in. Look at readdir(3) for the POSIX conforming C library
interface. This page documents the bare kernel system call interface, which is superseded by get‐
dents(2).

это НЕ та.

нужна man 3 readdir

#135812

хм... что-то я не оч догоняю...
вот предположим у меня такой файл "myfile.txt" лежит в любой папке, скажем, в \home\usr\mydir
как мне вот этот вот самый путь получить по вашему алггоритму?.. юзая эту функцию, получил айнод "myfile.txt"... далее?

#135817
c-villain написал:
"myfile.txt" лежит в любой папке, скажем, в \home\usr\mydir
как мне вот этот вот самый путь получить по вашему алггоритму?.. юзая эту функцию, получил айнод "myfile.txt"... далее?

получите inode не файла, а пути. т.е. путь у вас aaa/../../.././bb/cc/ (до первого слеша), вот его inode и получайте. потом распутайте от него через две точки настоящий полный путь.
(т.е. прочитайте каталог "..", тогда узнаете во первых имя этого каталога, во вторых инод каталога верхнего уровня, в третьих, проверите, корень-ли это. инод корня равен иноду "..")

Для упрощения алгоритма к имени можно прибавить вначале "./", а потом отрезать всё, после последнего слеша.

stat() ЕМНИП тоже там зачем-то нужна была. Уже и не помню, а искать код лень.

#135822
drBatty написал:
получите inode не файла, а пути.

так в том-то и дело, что путь я не знаю... у меня есть только название файла. больше ничего.

#135824
c-villain написал:
у меня есть только название файла. больше ничего.

тогда у вас только единственный способ - рекурсивно обойти все каталоги. метод я уже указал.
или этот файл == команда?
тогда посмотрите переменную окружения $PATH того юзверя, который запускает эту команду, и ищите только там. Программы не запускаются просто так, только в неком окружении.

#135825
drBatty написал:
рекурсивно обойти все каталоги

оО... т.е. получить сначала айнод самого файла... а потом, начиная с корня, обходить все директории и получить айноды всех файлов в директориях и сравнивать его с исходным айнодом?.. типа если совпал - значит нашлась директория...
омг...

Войдите или зарегистрируйтесь, чтобы ответить.