#c #c #unix
#c #c #unix
Вопрос:
В моем приложении на c я хочу изменить рабочий каталог на указанный. Но когда я указываю "~/dev/"
как рабочий каталог chdir()
, происходит сбой и возвращается -1. Вместо этого это работает, когда я указываю "/home/myusername/dev"
. Почему это происходит? Как я могу решить эту проблему (кроме проверки, является ли строка первым символом ~
и замены его на /home/myusername
)?
Комментарии:
1.
chdir("$HOME/dev/")
тоже сбой, и по той же причине.
Ответ №1:
Расширение tilde (~) в переменную среды HOME выполняется с помощью bash. Это расширение выполняется до того, как оно передается команде chdir. Суть в том, что ~ обрабатывается bash, а не командой chdir. Таким образом, вы не можете использовать его при вызове функции chdir().
Чтобы найти другие расширения (и подробности ~ expansion), выполненные bash, проверьте эту ссылку.
Ответ №2:
Вы могли бы использовать следующее, чтобы получить то, до чего ~
, вероятно, будет расширено (используя getpwuid
):
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
#include <pwd.h>
// @prefer_env should be TRUE if you prefer the value of the $HOME
// environment variable over what is stored in the user's passwd
char* get_homedir(int prefer_env)
{
char *found = getenv("HOME");
char *homedir = NULL;
if (!prefer_env || !found)
{
struct passwd *pw = getpwuid(geteuid());
if (pw amp;amp; pw->pw_dir) found = pw->pw_dir;
}
if (found)
{
// I would add error checking
homedir = (char*)malloc(strlen(found) 1);
strcpy(homedir, found);
}
return homedir;
}
Комментарии:
1. Этот код не проверяет переменную среды HOME, которая может переопределить путь, указанный при вводе пароля, другим значением.
2. @Al Riddoch: Я всегда с подозрением отношусь к этой переменной окружения, но это просто основано на опыте. Я обновлю свой код, чтобы использовать либо то, либо другое.
3. Для кода, запускаемого от имени пользователя, с чистыми пользовательскими привилегиями, вы всегда должны читать
HOME
, чтобы предоставить пользователю максимальную гибкость. Для кода, выполняющего какой-либо авторитетный поиск в домашнем каталоге пользователя с точки зрения повышенных привилегий, вы всегда должны использоватьgetpwuid_r
.
Ответ №3:
Разрешение ~
, как и любой переменной окружения, зависит от командной строки. Я не думаю, что вы можете использовать это в функциях C api.
Ответ №4:
Ну, в вашем домашнем каталоге ~ обычно заменяется вашей оболочкой, когда вы вводите его перед тем, как оболочка вызовет какой-либо программный вызов (даже если cd не является программным вызовом, а реализован в самой оболочке).
В любом случае: в C нет способа автоматически заменить ~ на ваш homedir
Ответ №5:
Как указано в предыдущих ответах, библиотека C не заменяет ~ для вас. Это делается командной оболочкой. Не следует предполагать, что домашним каталогом пользователя является /home/myusername, поскольку этого нельзя предположить.
Правильный способ определить домашний каталог — это проверить наличие переменной среды HOME и прочитать ее содержимое. Обычно это будет определено, но в случае, если это не так, вам следует вернуться к использованию getpwuid() или аналогичного вызова, чтобы получить ввод пароля для текущего пользователя, который будет включать его домашний каталог.
Ответ №6:
Попробуйте вместо этого использовать $HOME, ~ — это просто ярлык для $HOME.
Комментарии:
1. На самом деле оболочка все равно расширит ~ до вашего домашнего каталога, если $HOME не задан, так что это не так просто, как ярлык для $HOME.