10

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?

14

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 if you do 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

  • Instead of changing UID and GID, we can just useradd 'tmp' and then replace tmp with ~ – VarunAgw Sep 29 '15 at 20:38
  • 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
8

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.

1

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
0

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
  • 2
    Well, cd ~~/foo/bar isn't going to work so well, or vim ~~/foo.txt, etc... – derobert Sep 29 '15 at 20:03
  • 1
    The 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.