"Can't cd to /home/user" when sourcing a script

54,003

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 example sh script.sh, as #!/bin/bash was ignored since you explicitly asked to run the script with sh, 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

Share:
54,003

Related videos on Youtube

Karlovsky120
Author by

Karlovsky120

Updated on September 18, 2022

Comments

  • Karlovsky120
    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 (invoking cd $HOME from within $HOME simply didn't change directory).

    What must I do to make this work?

    • Admin
      Admin almost 10 years
      What 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 as sh script.sh.
    • Admin
      Admin almost 10 years
      Did you import that script from a Windows machine? If that's case try to convert it to UNIX format with the dos2unix command.
  • Karlovsky120
    Karlovsky120 almost 10 years
    How 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'
    G-Man Says 'Reinstate Monica' almost 10 years
    If 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'
    G-Man Says 'Reinstate Monica' almost 10 years
    And if you can't find the '>' character, try dd if=script iflag=text of=new_script.
  • vinc17
    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
    Karlovsky120 almost 10 years
    I 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
    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. try your_script 2>&1 | cat -ve : -v to show special chars, -e to end lines with $
  • vinc17
    vinc17 almost 10 years
    @OlivierDulac Thanks. I've added explanations in my answer, based on your comment.
  • Anthon
    Anthon about 9 years
    How do I install Notepad++ on Debian systems?
  • moerion
    moerion about 9 years
    I have never done it myself but a quick google search lead to this: sourcedigit.com/…
  • Aadishri
    Aadishri almost 7 years
    Install Notepad++ using Wine on Linux