Advertisement

[ Linux ] How does the tilde/ work?

Started by October 27, 2010 05:07 PM
12 comments, last by Sneftel 14 years, 1 month ago
I am wondering whether I can use ~/ as a valid replacement for trying to get the current user's home directory from the HOME environment variable.

So the thought would be that if getenv( "HOME" ) fails, I would then try using "~/". But if "~/" also uses the HOME env. var., it won't work.

Hmm... I will test this by setting the HOME env. var. to an invalid value and see what happens when I use "~/".

Hmm, wait, can I screw up my system if I mess with the HOME var.? Perhaps I will not try this yet. What do you think...?

This is certainly not a big deal to me - I am just curious about how the ~/ works so if anyone knows please do tell me.
I think it is better to use getlogin() in combination with getpwent() to read the path to the home directory.
See also http://www.gnu.org/manual/gawk/html_node/Passwd-Functions.html

#include <stdio.h>#include <string.h>#include <sys/types.h>#include <unistd.h>#include <pwd.h>int main(){	struct passwd *p;	char* login = getlogin();	while ((p = getpwent()) != NULL)	{		if(strcmp(login,p->pw_name)==0)			break;	}	printf("%s\n",p->pw_dir);	endpwent();	return 0;}
Advertisement
The ~ is a shell expansion, you cannot use it as a path to file functions from within your program, unless you are shell scripting.
A-ha. I will research that. So this should be more reliable?

Thanks for the links. I'll go and try this method.



However if anyone can explain how the ~/ works I would be interested to hear. It's not critical... just out of curiosity.
Quote: Original post by reptor
A-ha. I will research that. So this should be more reliable?

Thanks for the links. I'll go and try this method.



However if anyone can explain how the ~/ works I would be interested to hear. It's not critical... just out of curiosity.


as rip-off said, its all in the shell and exactly how its done (if at all) can vary between shells.

For Bash you can get it all right here: http://www.network-theory.co.uk/docs/bashref/TildeExpansion.html
[size="1"]I don't suffer from insanity, I'm enjoying every minute of it.
The voices in my head may not be real, but they have some good ideas!
Quote: Original post by rip-off
The ~ is a shell expansion, you cannot use it as a path to file functions from within your program, unless you are shell scripting.



Well that clears it up then.

I am writing programs in C++ and I try to ensure that there is a reliable way to find the required directories. I don't trust the environment variables much and would rather avoid them completely which is what I am doing now with this.
Advertisement
I just looked how Qt finds the home folder and it uses getenv("HOME").
I don't think any user will change the variable without a really good reason, so getenv("HOME") is pretty safe to use. If a user wants you to think the home folder is /home/user/my_home, why not accept this? It depends on why you need to know the home folder.
I used "../../" in a path with std::ofstream and it worked as expected. I started the program from a bash shell.

But using "~/" in a path with std::ofstream doesn't work. I started the program from a bash shell.


So the dots are different, it appears. Can anyone explain why the dots work but the tilde doesn't?
Quote: Original post by reptor
Quote: Original post by rip-off
The ~ is a shell expansion, you cannot use it as a path to file functions from within your program, unless you are shell scripting.



Well that clears it up then.

I am writing programs in C++ and I try to ensure that there is a reliable way to find the required directories. I don't trust the environment variables much and would rather avoid them completely which is what I am doing now with this.


Actually you can use tilde expansion from your own program if you use the wordexp function.

http://www.kernel.org/doc/man-pages/online/pages/man3/wordexp.3.html


Quote: Original post by reptor
I used "../../" in a path with std::ofstream and it worked as expected. I started the program from a bash shell.

But using "~/" in a path with std::ofstream doesn't work. I started the program from a bash shell.


So the dots are different, it appears. Can anyone explain why the dots work but the tilde doesn't?


because ../ is a relative pathname, it is part of the system, tilde expansion (along with things like command and variable substitution) are not, those are part of the shell. (It doesn't matter if you launch your application from the shell or not, the shell is an application on its own and only parses commands (or scripts) and launches your application)

(the wordexp function handles all of those though)
[size="1"]I don't suffer from insanity, I'm enjoying every minute of it.
The voices in my head may not be real, but they have some good ideas!
Kambiz, I try to make the application very robust to these sort of things.

The user can give a directory into which the process can't write, for example. I just try to make sure that the application will always find the user's home directory irrespective of configuration changes done by the user.

I will in fact provide a way for the user to give the application a "profile" directory so it will be possible to change where it stores its user-specific data. But even then I will be checking if that directory actually is okay and if it isn't then I will have the application fall back to the user's real home directory.

This topic is closed to new replies.

Advertisement