Change script directory to user's homedir in a shell script - linux

In my bash script I need to change current dir to user's home directory.
if I want to change to user's foo home dir, from the command line I can do:
cd ~foo
Which works fine, however when I do the same from the script it tells me:
./bar.sh: line 4: cd: ~foo: No such file or directory
Seams like it would be such a trivial thing, but it's not working. What's the problem here? Do I need to escape the "~" or perhaps missing quotes or something else?
Edit
when I say user I don't mean current user that runs the script, but in general any other user on the system
Edit
Here is the script:
#!/bin/bash
user="foo"
cd ~$user
if username is hardcoded like
cd ~foo
it works, but if it is in the user variable then it doesn't. What am I missing here?

What about
cd $(getent passwd foo | cut -d: -f6)
and
USER=foo
eval cd ~$USER
works, too (foo is the username)

Change it to:
cd $HOME
Actually, I'm not sure why cd ~whatever wouldn't work. I've just tested with a small script and it worked fine:
#!/bin/bash
cd ~sbright
I actually get the same error message that you do when the specified user does not exist on the system. Are you sure (and yes, I know this is one of those is-it-plugged-in questions) that the user exists and has a valid home directory specified?
Edit:
Now that I see what you are actually doing... tilde expansion happens before variable interpolation, which is why you are getting this error.

Is the script going to be run by the user? If it is you can just do:
cd ~

Is there some reason you can't do:
#!/bin/bash
cd /home/$USER
Of course directories aren't in /home on all *nixes, but assuming you know what OS/distro your script is targeted for, you should be able to come up with something that works well enough.

Related

One command to create and change directory

I'm searching for just one command — nothing with && or | — that creates a directory and then immediately changes your current directory to the newly-created directory. (This is a question someone got for his exams of "linux-usage", he made a new command that did that, but that didn't give him the points.) This is on a debian server if that matters.
I believe you are looking for this:
mkdir project1 && cd "$_"
define a bash function for that purpose in your $HOME/.bashrc e.g.
function mkdcd () {
mkdir "$1" && cd "$1"
}
then type mkdcd foodir in your interactive shell
So stricto sensu, what you want to achieve is impossible without a shell function containing some && (or at least a ; ) ... In other words, the purpose of the exercise was to make you understand why functions (or aliases) are useful in a shell....
PS it should be a function, not a script (if it was a script, the cd would affect only the [sub-] shell running the script, not the interactive parent shell); it is impossible to make a single command or executable (not a shell function) which would change the directory of the invoking interactive parent shell (because each process has its own current directory, and you can only change the current directory of your own process, not of the invoking shell process).
PPS. In Posix shells you should remove the functionkeyword, and have the first line be mkdcd() {
For oh-my-zsh users: take 'directory_name'
Reference: Official oh-my-zsh github wiki
Putting the following into your .bash_profile (or equivalent) will give you a mkcd command that'll do what you need:
# mkdir, cd into it
mkcd () {
mkdir -p "$*"
cd "$*"
}
This article explains it in more detail
I don't think this is possible but to all people wondering what is the easiest way to do that (that I know of) which doesn't require you to create your own script is:
mkdir /myNewDir/
cd !$
This way you don't need to write the name of the new directory twice.
!$ retrieves the last ($) argument of the last command (!).
(There are more useful shortcuts like that, like !!, !* or !startOfACommandInHistory. Search on the net for more information)
Sadly mkdir /myNewDir/ && cd !$ doesn't work: it retrieves the last of argument of the previous command, not the last one of the mkdir command.
Maybe I'm not fully understanding the question, but
>mkdir temp ; cd temp
makes the temp directory and then changes into that directory.
mkdir temp ; cd temp ; mv ../temp ../myname
You can alias like this:
alias mkcd 'mkdir temp ; cd temp ; mv ../temp ../'
You did not say if you want to name the directory yourself.
cd `mktemp -d`
Will create a temp directory and change into it.
Maybe you can use some shell script.
First line in shell script will create the directory and second line will change to created directory.

command not found in bash-3.2$

I tried running a script file using bash but it showed an error
bash-3.2$ example.sh : command not found
I also tried
ls -l example.sh
I found that it was not executable, so I used
sudo chmod 777 example.sh
I again tried running it but same error was coming. I double checked that I am in the same folder as the file using ls. But still I am not able to execute the script file.
I finally tried making a dummy script file and running it , and found the same error
I think there is some problem with BASH. Can some one help me with what is the problem?
I am working on redhat, bash was already installed in my system
Since I am newbie on linux any help would be appreciated
bash search for commands in your $PATH. Apparently the current directory, ., is not in your $PATH. (This is a good thing; having . in your $PATH is insecure.)
You'll need to specify a directory name. Just type:
./example.sh
Incidentally, doing:
sudo chmod 777 example.sh
is two kinds of overkill. First, you don't need to use sudo; use sudo only when you actually need to. Presumably your personal account owns the file, so you can just use chmod directly.
Second, 777 is way too permissive. It allows anyone on the system to read, execute, or modify example.sh. (If you're the only person on the system it may not matter much, but it's still a bad habit.) Typically you should use 755 for directories and for files that need to be executable, and 644 for files that don't need to be executable.
Or just use
chmod +x example.sh
to set execute permission (your umask will prevent that from setting the permissions too loosely).
. (the current directory) is probably not on your path. Try ./example.sh or bash example.sh. You could also add . to your PATH environment variable, but that's generally frowned upon.
Your bash PATH probably doesn't include ., try running it by typing:
./example.sh
When you type a command, your shell searches your path to try to find the command, if the current directory (e.g. .) isn't part of the path, the script that you are trying to run won't be found. You'd have to explicitly give it the path to where this command is. And since it's in your current directory, you can just add ./ in front of the command.
first confirm the bash path
to check the path of bash use:
which bash
if you get "/bin/bash"
then add
#!/bin/bash
...
...
or whatever is the path on first line of your bash script

Changing directory echoes "Directory: <pwd>"

I have an annoying problem when using Screen on my SLED10 machine. When changing directory (cd, chdir, pushd/popd) the resulting path is echoed in the terminal.
user#/home/user> cd ..
Directory: /home
user#/home>
This problem only seem to exist in Screen. I have checked my prompt and it does not contain anything related to this behavior. I am using tcsh/xterm.
How do I get rid of the echo of the directory?!
Best Regards,
Stefan
Maybe cd has been overridden with an alias or a function.
Once in screen, use:
alias cd to see if there is an alias and declare -f to check your functions.

creating a reference for script

I want to make the following kind of reference:
"ls" command, for example, is universally available in most *nix environments. User can type in from anywhere to execute the scripts.
So, I write script "x". I want to make sure that from wherever the user type in x, the actual script "x" is referenced.
Thus, if I have script "x" stored in home/user/Desktop directory, I should not have to reference the script as follow:
home/user/Desktop/x
I should be able to do:
x
Thanks!
You want to add the directory to your PATH. E.g.
PATH="$PATH:/home/user/someDirectory"
You can add this line to .bash_profile to do it on startup. However, you probably shouldn't add Desktop to the path because some browsers download to there by default (though it shouldn't be executable by default).
You can also put your script in an existing directory that's already in your path such as /usr/local/bin or create a symlink there to your script's location.
cp /home/user/Desktop/x /usr/local/bin
or
mv /home/user/Desktop/x /usr/local/bin
or
ln -s /home/user/Desktop/x /usr/local/bin
Don't mean to be obnoxiously repetitive, but this is my first time answering a question, I can't reply to someone's already-good answer, and I think they are missing some important bits.
First, if you want to make sure everyone can access the script, you'll need to be sure everyone has execute permissions:
chmod a+x /path/to/script.sh
You'll also want to make sure it's in somewhere $PATH references (as the other answers mentioned):
echo $PATH # place the script in one of these directories
I would personally prefer /usr/local/bin, since that's considered the place for custom global scripts. Something the other answers didn't mention is that, if you do want to use a directory besides one in $PATH (say, /opt/myscriptfolder/) you'll want to add another PATH entry at the end of /etc/profile:
PATH="$PATH:/opt/myscriptfolder/"
By putting this in the end of /etc/profile, all users will receive this modified PATH variable on their next login.

implementing cd command using chdir() in linux

I am writing my own shell program. I am currently implementing the cd command using chdir.
I want to implement the chdir with the below options :
-P Do not follow symbolic links
-L Follow symbolic links (default)
I posted a question here previously asking to know if a path is a symbolic link or actual path. But with that info I am unable to get any ideas on how to proceed with the above problem.
Thanks
Maybe I'm misunderstanding, but you just want (pseudocode):
is_symlink = method_from_other_question();
if(is_symlink and arg(-P))
fail("Can't switch directory -- is a symlink");
If you've already tried something like this and it doesn't work, include the code in your question and we can help debug it
Shells generally do a lot of trickery to find the real dir name. And they also fake a lot of stuff for our user's convenience. E.g.:
$ pwd
/home/auser
$ ls -l
adir -> some/place/
some/
$ cd adir
$ pwd
/home/auser/adir
$ cd ..
$ pwd
/home/auser
Looks logical? Then look again: the .. in /home/auser/some/place points to /home/auser/some, not /home/auser yet cd .. took you to the later.
IOW, there is no other way but to always keep in memory the absolute path of the current directory and parse it fully (and check every element of it) when doing cd.
And yes, it is not reliable. In past on one occasion I have managed to fool bash and it was showing totally wrong absolute path for my current directory.

Resources