"Can't cd to /home/user" when sourcing a script
Solution 1
You have CR (^M) characters in your script. Convert it to have Unix end-of-lines (only LF). In a portable way:
tr -d '\r' < your_script > output_script
Some explanations based on Olivier Dulac's comment about what happened with CR characters: First, in the shell language, the CR character is not regarded as a special character, e.g. not regarded as a space and not ignored. I write it as ^M
below.
In the
echo $HOME^M
line, the content of$HOME
followed by^M
followed by a new line was output. Outputting the CR character put the cursor on the first column, but since it was immediately followed by a newline, this had no visible effect.-
In the
cd $HOME^M
line, since there is no space between$HOME
and the CR character, they are both in the same argument$HOME^M
, and this directory does not exist. In the error message, the CR character after$HOME
was just output, putting the cursor on the first column, so that the beginning of the line was overwritten by the rest of the message if any: ": No such file or directory" with bash (your first example), nothing with dash (your second examplesh script.sh
, as#!/bin/bash
was ignored since you explicitly asked to run the script withsh
, which seems to be dash in your case). The error message completely depends on the shell. For instance, zsh detects that the CR character is not printable and outputs a message like:cd: no such file or directory: /usr/local/src/^M
(with the characters "^" and "M", not the CR character), which allows one to detect the cause of the problem much more easily. Otherwise you need to redirect/pipe stderr to some utility that can show special characters such as cat -ve
as suggested by Olivier, or to hd
, which gives the byte sequence for the stream.
Solution 2
If you use set -x
you will notice why sourcing the file is failing:
$ . test.sh
+ . test.sh
++ echo $'/home/braiam\r'
/home/braiam
++ cd $'/home/braiam\r'
: No such file or directory
++ cd $'/\r'
: No such file or directory
++ cd $'/usr/local/src/\r'
: No such file or directory
As vinc17 said, just remove the \r
part of your script and you will be fine. You can use his solution, or using dos2unix script.sh
, also sed -i 's/\r//' script.sh
Solution 3
You can use the below command as well to remove the CR characters.
perl -p -i -e "s/\r//g" script.sh
If you are using vi/vim, you could do,
:set ff=unix
Solution 4
I had this same problem and I fixed it by converting the EOL characters to UNIX format. An easy way to do it is:
- Load the file into Notepad++
- Select all of the text to be converted (Ctrl + A)
- Edit > EOL Conversion > UNIX
- Save the file
If already in UNIX format, select another format (Windows) and then back into UNIX
Related videos on Youtube
Karlovsky120
Updated on September 18, 2022Comments
-
Karlovsky120 almost 2 years
I have this script:
echo $HOME cd $HOME cd / cd /usr/local/src/
When I run it like this
. script.sh
I get this output:
/home/user : No such file or directory : No such file or directory : No such file or directory
If I run it normally (I added
#!/bin/bash
before the first line)sh script.sh
I get this output:
: not found.sh: 2: script.sh /home/user script.sh: 3: Can't cd to /home/user script.sh: 4: Can't cd to / script.sh: 5: Can't cd to /usr/local/src/
The script was run from
$HOME
directory each time. If I run each command one by one from shell, it executed without problems (invokingcd $HOME
from within$HOME
simply didn't change directory).What must I do to make this work?
-
Admin almost 10 yearsWhat is your default shell? Is this the exact script you are using? None of these errors make sense. As a side note, there is no reason for the
#!/bin/bash
if you run the script assh script.sh
. -
Admin almost 10 yearsDid you import that script from a Windows machine? If that's case try to convert it to UNIX format with the
dos2unix
command.
-
-
Karlovsky120 almost 10 yearsHow do I do that? I can't enter `\` character in the terminal... Alt Gr + Q doesn't work, which is how I usually type it...
-
G-Man Says 'Reinstate Monica' almost 10 yearsIf you really can't generate a '\' character, run
dos2unix
or equivalent (e.g.,dd if=script iflag=text > new_script
), or delete the carriage returns some other way, there's a last-resort kludge hack: put a space and a#
at the end of each line of the script. -
G-Man Says 'Reinstate Monica' almost 10 yearsAnd if you can't find the '>' character, try
dd if=script iflag=text of=new_script
. -
vinc17 almost 10 years@Karlovsky120 All QWERTZ keyboards have < and > keys. Instead of using alternative commands (
dd iflag=text
is not standard), you should better learn where they are. -
Karlovsky120 almost 10 yearsI installed Notepad++ and am writing scripts using it. It has an option to use linux/unix EOL, so all works as it should...
-
Olivier Dulac almost 10 years+1, but maybe add just an explanation: in linux, the CR (Carriage return) (^M) extra character causes the cursor to return to the beginning of the line. And it is also interpreted as part of the directory names. So it really says something like
cd: /^M: No such file or directory
and the ^M place cursor at the beginning, so the rest of the message "overwrites" the beginning. In the 2nd example, cursor only comes back to beginning as the last character on the line, therefore it's "invisible" that it does so. tryyour_script 2>&1 | cat -ve
: -v to show special chars, -e to end lines with$
-
vinc17 almost 10 years@OlivierDulac Thanks. I've added explanations in my answer, based on your comment.
-
Anthon about 9 yearsHow do I install Notepad++ on Debian systems?
-
moerion about 9 yearsI have never done it myself but a quick google search lead to this: sourcedigit.com/…
-
Aadishri almost 7 yearsInstall Notepad++ using Wine on Linux