I want ~~ to point to a different directory so I can use it as a shortcut. I want it to have exactly same functionalities as ~. How can I do this?
-
2You might be better off with [zsh named directories](http://zsh.sourceforge.net/Doc/Release/Expansion.html#Static-named-directories) – Michael Mrozek Sep 29 '15 at 20:05
-
Just found an interesting solution to the problem http://superuser.com/a/565825/398328 – VarunAgw Sep 29 '15 at 20:29
-
1@VarunAgw haha, Funny find, right as I had thought of the same solution. Shame. I thought i was a unique butterfly for a minute :( – Gravy Sep 29 '15 at 20:37
4 Answers
Actually, there is a way, it's not a great way, but it's a way, haha!
Add the following to your /etc/passwd file:
~:x:1111:99:special Character user:/test:/sbin/nologin
replace the 1111 as the UID with something that makes sense, replace /test with the directory you want ~~ to mimic.
99 on my system is the nobody group. I recommend you to do this to make sure it's a group with no permissions on any file that will ever get used. Theoretically with /sbin/nologin as the shell, it should not be able to be used, it also will not have an /etc/shadow entry so it won't have a password. Theoretically should be fine, but make sure that it doesn't somehow let you log in as the account.
As a side note: I am not in any way saying this is a good idea, but it will accomplish the functionality that you want.
EDIT: For completeness’ sake this was suggested by @VarunAgw:
You could add the user as normal with useradd -s /sbin/nologin -N tmp and then modify /etc/passwd and /etc/shadow to change the user tmp to ~ and change the location of the home directory.
-
True. good suggestion. I'm unsure how i feel about legitimizing it with a `shadow` entry but i suppose as long as no password is set its not really an additional risk. – Gravy Sep 29 '15 at 20:47
-
Old question/answer, I know, but it surfaced when someone asked it again yesterday (and we didn't realize it was a duplicate until the question's title was edited). I came up with almost the [same answer](https://unix.stackexchange.com/a/658158/432493). Note that `useradd --badname --no-user-group --non-unique -u 1000 -g 1000 --shell /sbin/nologin -f0 -e0 --home-dir
"~"` pretty much gives you everything in one command line. See my linked answer for more details on the results. – NotTheDr01ds Jul 13 '21 at 18:17
You can make use of CDPATH and put a directory literally named ~~ in one of your CDPATH components.
From man bash (but CDPATH is available even in sh)
The search path for the cd command. This is a colon-separated list of directories in which the shell looks for destination directories specified by the cd command. A sample value is ".:~:/usr".
That will allow you to do cd ~~.
If you want to do things like vi ~~/someFile from anywhere in the directory tree, then you're out of luck if you insist on ~~ literally unless you hack your shell, however, you can use variables or environment variable to store your magic directories so you can do, e.g, $tilda/someFile
I usually put often-accessed files inside shortly named directories in my home directory so I can access them with paths such as ~/b or ~/l.
Naturally, you can usually replace directories with symlinks to directories as much as you want.
- 28,176
- 14
- 81
- 141
The shell's ~ tilde expansion is mostly programmable. It expands either to the user directory of the system username declared in its trailing context (and an excellent solution along these lines has already been offered), the value of the $HOME shell variable, or not at all.
So:
(HOME=/tmp; cd ~)
pwd; echo "$HOME"
/tmp
/home/mikeserv
I change $HOME all of the time, and I keep a function in my shell's environment file for resetting it:
home(){
HOME=~$USER
cd ~; pwd
}
If you want to use the ~ tilde in some way that doesn't refer to your home directory, then do so. Just reassign $HOME. Don't be afraid of it. $HOME is just a shell variable like any other.
Another suggestion I have is only a slight expansion on @PSkocik's excellent advice about using $CDPATH. One thing he didn't mention, though, is that you can use and alter $CDPATH inline without changing the current shell value for $CDPATH at all. For example:
mkdir -p /tmp/1/2
CDPATH=/tmp cd 1/2
/tmp/1/2
cd is necessarily a shell builtin, but it is not a POSIX special shell builtin, and so declaring the value for $CDPATH doesn't affect its current shell value. If you use it as I did above $CDPATH's value is only altered for the environment of the one cd command, and is restored to its previous value afterward. I tend to find the above technique most useful when used in combination with history completion. I'll do the above thing, change to a directory, run a few commands, then press up until I come back to my cd command and backspace a path segment or two to move elsewhere.
Now if you combine these two concepts then you can make a previously used command mean something entirely different the next time you use it.
for HOME in /tmp ~
do mkdir -p ~/1/2
CDPATH=~ cd 1/2
done
/tmp/1/2
/home/mikeserv/1/2
- 57,448
- 9
- 113
- 229
Works perfectly well as a bash function:
$ function ~~ { cd /tmp; }
$ pwd
/home/jackman
$ ~~
$ pwd
/tmp
$ cd -
$ pwd
/home/jackman
Here's another approach that comes a little closer (I know I'm not getting that close the to requirements)
function ~~ { echo /test; }
Then with a couple more characters:
cd `~~`/subdir
vi `~~`/file
- 84,176
- 15
- 116
- 168
-
2Well, `cd ~~/foo/bar` isn't going to work so well, or `vim ~~/foo.txt`, etc... – derobert Sep 29 '15 at 20:03
-
1The question is unclear. If that's the desired usage, I'd use the `CDPATH` variable to handle the `cd` case. – glenn jackman Sep 29 '15 at 20:07
-
Agree it's not fully clear, but OP does ask for it to work like `~`. And `~` is not used like a command. – derobert Sep 29 '15 at 20:09
-
I found it fairly understandable myself, if not completely spelled out. The problem with `CDPATH` is it doesn't work for commands outside of....CD. IE you could `cd ~~` or `cd ~~/testdir1` but you could not `vim ~~testdir1` – Gravy Sep 29 '15 at 20:17
-
you might do better with an alias that calls a function. like `alias cd~='HOME=$OTHER_HOME; home(){ cd -- "$1"; HOME=~$USER; unset -f home;}; home '` – mikeserv Sep 29 '15 at 22:19