Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I want to add an alias file to my project folder to quickly open and edit files in it with a simple shell command.
To make it more portable, I would like to use only relative paths.
I want something like this:

### .profile

source /my/project/folder/aliases.bash

and

### aliases.bash

alias editprojectfiles="edit [/my/project/folder/]afile.txt"

The problem for me now is how to retrieve [/my/project/folder/] automatically. I tried to use $PWD variable, but the result is that the alias points to the folder of .profile file and not the aliases.bash ones. Is there a way to get this?

UPDATE

Some user point me out to the $PWD solution.
This does not work, since the $PWD variable is relative to the path of the source command, not to the project one.
So I doing this

### .profile

$~/>source /my/project/folder/aliases.bash

### aliases.bash

alias editprojectfiles="edit $PWD/afile.txt"

Will create an alias like this

editprojectfiles="edit /my/user/home/folder/afile.txt"

And doing this

### Call source from folder /foo/bar

$/foo/bar>source /my/project/folder/aliases.bash

### aliases.bash

alias editprojectfiles="edit $PWD/afile.txt"

Will create an alias like this

editprojectfiles="edit /foo/bar/afile.txt"

share|improve this question
    
Why aren't you using the alias command? As it is your aliases.bash file is actually defining environment variables, not aliases. –  Parthian Shot Jun 2 at 16:00
    
Sorry, I missed the alias in copy&paste. Fixed it now. –  pasine Jun 2 at 16:47

2 Answers 2

up vote 2 down vote accepted

Use single quotes:

alias editprojectfiles='edit $PWD/afile.txt'

Even better, use this in case you had whitespace in directory name:

alias editprojectfiles='edit "$PWD"/afile.txt'

EDIT:

After reading your comments to savanto's reply I think that what you want to have is the following:

  • you have afile.txt in a your current project folder
  • you edit this file
  • you move on to a different project and mv afile.txt to a new project folder
  • you still want to edit afile.txt in a new project folder

Basically you want to edit the same afile.txt regardless of its location. Every file on filesystem is ambiguously identified by inode number. You can see inode number next to filename using -i switch in ls command:

$ ls -Alhi
total 4.0K
8013300 -rw-r--r-- 2 ja ja 10 Jun  3 11:38 afile.txt

Here 8013300 is inode number. After moving a file to a different location within the same filesystem its inode number does not change. Now you need to create a hardlink pointing to afile.txt. Hardlinks are different from symlinks. Hardlink has the same inode number as the target file. And as I said, file's inode stays the same even if the file is moved so even if you move original afile.txt to a new directory hardlink still will point to file in a new directory.

Use ln command to create hardlink:

$ ln path/to/afile afile

If you did it in your home directory afile will be created and will have the same inode as path/to/afile. Try to edit ~/afile and check if path/to/afile is also changed. Try moving path/to/afile to a different dir, edit ~/afile and again check whether afile in a new location looks the same - it should.

If it works for you make your alias look like this:

alias editprojectfiles="edit ~/afile.txt"

EDIT:

I don't think there is a way to do that using only alias command in ~/project/aliases.bash. You need to pass a variable to alias command that is set before alias command. In your case, this variable is path where alias.bash resides. Your aliases.bash should look like this:

DIR="$(dirname ${BASH_SOURCE[0]})";
alias editprojectfiles="edit $DIR/afile.txt"

$DIR is a path to your project folder. Subsequent invocations of editprojectfiles will refer to $DIR directory that will always be the same.

share|improve this answer
    
Enclosing $PWD makes the alias taking $PWD as a string and not as a variable. –  pasine Jun 2 at 16:53
    
Are you trying to say that it doesn't work for you? Enclosing $PWD in single quotes in alias causes it to be passed directly as $PWD to shell as dollar signs are not treated specially within single quotes in contrary to double quotes. When you start new shell instance $PWD is not substituted with a directory where shell startup script is located. –  Arkadiusz Drabczyk Jun 2 at 17:03
    
Exactly. It is not working. The resulting alias is alias editprojectfiles='edit "$PWD"/afile.txt'. When I lunch it, it open the editor with an empty afile.txt in the current folder. –  pasine Jun 2 at 19:28
    
So what do you want to do? What is [/my/project/folder/] supposed to mean? Is it always the same directory, current directory or a directory relative to the current one? –  Arkadiusz Drabczyk Jun 2 at 19:38
    
I want to be able to edit afile.txt from whatever directory I am in using a command and I don't want to use absolute paths since the folder could be moved. –  pasine Jun 2 at 20:22

You could search for the file every time you try to access it. Using locate if you have it:

alias editprojectfiles='edit "$(locate -n 1 "afile.txt")"'

Note: -n limits the results. On some systems it's -l instead. See your locate man page.

Note: locate uses a database that is updated periodically, but will not always be up to date. The update frequency depends on your system. If you need up-to-the-minute file locations, use find.


Somewhat slower (but possibly more universal?) is to use find:

alias editprojectfiles='edit "$(find ~ -name "afile.txt" -print -quit)"'

You could make it faster by narrowing the search range, by being more specific than ~ for the root directory, or controlling the depth.

Alternatively

To prevent searching every time you use your alias, you could do the search once upon login, and it will hold for the duration of your session. To do this, in your aliases file, use locate or find and assign it to a variable and then use that variable within the alias:

AFILE="$(find ~ -name "afile.txt" -print -quit)"
alias editprojectfiles="edit \"$AFILE\""

Note: double quotes to allow variable expansion.

This will not, however, keep track of the file if you move it within your session. But if you start a new session, the new location will be updated.

share|improve this answer
    
This looks to me really unreliable: what if I have two files with the same name? –  pasine Jun 3 at 7:47
    
@notme A file is uniquely identified on a system by its full path, and can be accessed using this path from anywhere else on the system. No two files may have the same path on the system, as then they would conflict. However, your requirement is to access a file from anywhere on the system using only its file name. Hence, you will need to make sure the filename is unique, or at least unique within the top level of the search directory. –  savanto Jun 3 at 13:23
    
@notme You could try the hard link approach in the answer by Arkadiusz Drabczyk , but you will still need to name your link uniquely within the directory in which it will reside. –  savanto Jun 3 at 13:34

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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