1

This question already has an answer here:

#!/bin/bash
#
echo $PWD
cd /home/<my username>/<long path>
echo $PWD

What I get when executing it with bash script.sh:

/home/<my username>
: No such file or directorye/<my username>/<long path>
/home/<my username>

Or with bash . script.sh

.: .: is a directory

It looks like in first case it has just skipped first 4 characters (/hom) of the address line for no reason. And in second case, what the hell is .: .:? It's absolutely "ungooglable".

And ofc when I copypaste this line cd /home/<my username>/<long path> in terminal it works like it should.

EDIT: IT WAS ALL ABOUT ONE MISSING SPACE SYMBOL AT THE END OF THE PATH, THANK YOU.

marked as duplicate by Jeff Schaller, sam, GAD3R, jayhendren, grochmal Dec 28 '16 at 20:29

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • When you run the script, a new instance/subshell will be created. Try sourcing the script using .[space]script.sh – Zwans Dec 28 '16 at 16:08
  • Maybe best duplicate: unix.stackexchange.com/a/27140/117549 – Jeff Schaller Dec 28 '16 at 16:11
  • 1
    "." is the current directory. When you say bash . script.sh you are asking bash to execute the current directory passing script.sh as $1. At the risk of confusing things more, probably what was being asked of you was . script.sh (without bash) or just possible bash -c ". script.sh". – icarus Dec 28 '16 at 16:19
  • 1
    We can't really help unless you show us the exact path and the actual script. I am willing to bet you have an \r character somewhere in there (did you maybe edit this from Windows?) and that's why it's eating the first few characters but I can't be sure unless you upload the script somewhere and link it here. – terdon Dec 28 '16 at 17:00
3

You should

  • check the script for any "hidden characters" before your "/home" part (that would explain it can't cd to it, and why the display truncates part of it too). For example: cat -ve THEFILE # -e will mark each end of line with a $ and -v will show some of the control characters in the form ^x, ex: ^M for the control character "Carriage Return".

  • Fix it: For this, type a working example in your shell, then copy it using the mouse, and edit the script, delete the line, and paste the one you copied in its place. (in vi: if the script is exactly as described (and the faulty line is line 4) : you go to line 4 with 4G, then delete that line with dd, and go in Insert mode on the line above with: O (capital o). Then you can paste the lines you copied with the mouse. then Escape to go back to command mode, and :wq to write the changes it the file and quit vi.

  • You may want to compare the output $(pwd) with the value $PWD: try to replace the : echo $PWD with : pwd ; echo "PWD=$PWD"

  • finally : bash . script.sh should be: bash ./script.sh . The one you typed ask bash to execute "." with the argument "script.sh", and "." being a directory, bash complains. When invoked in this way, the complaint is usually on the form: program_name: some message . Here bash tries to execute the program ., so its error message mistakenly use .: as the program name prompt, and the message it displays is .: is a directory, indicating that it couldn't execute it and why (it is a directory, not a bash script).

  • Note that when you invode script.sh in this way (bash ./script.sh), you ask your current shell to invoke a bashsubshell that will execute script.shand exit. Only that bash subshell will be: echoing PWD, then cd-ing to the directory, the echoing the new PWD. When that bash exits, your current shell is still in the original directory. If you want to have a file making changes in your current shell, source it instead: . ./script.sh or in bash you also can source ./script.sh (note: . is the more portable way to source a file) (note 2: having a path for the file to source is recommended in recent shell, ie: . script.sh may work too, but it is recommended to specify the local path such as: . ./script.sh)

  • There are only these ^M$ hidden characters and I assume it's a simple end of line. No hidden characters between "cd" and "/home/...." – Sigmund Freud Dec 28 '16 at 17:12
  • @SigmundFreud : if there is one just at the end of <longpath>, it is included in it and therefore that path becomes invalid. Add a space in between. or use: dos2unix <./script.sh >./script.sh_for_unix && mv ./script.sh_for_unix ./script.sh # to get rid of all those ^M, used in windows environment and causing those issues in an unix script. the < and > are needed in that command, and you shouldn't use it as a delimiter as you did in your question, as they are usually redirection commands (as in this command) – Olivier Dulac Dec 28 '16 at 17:16
  • 1
    OMG, I am in deep shock. Now it seems to work, thanks. – Sigmund Freud Dec 28 '16 at 17:18
  • @SigmundFreud: Glad it helped. you will have many similar missteps, but hang in there, unix scripting and its environment is worth it ! Read the wooledge.com site's "bashFAQ" "bash pitfalls" and "bash guide" pages, and you'll spare yourself a LOT of similar mistakes ^^ – Olivier Dulac Dec 28 '16 at 17:20
  • 1
    thanks, where can I + your rep now? Can't find it anywhere. – Sigmund Freud Dec 28 '16 at 17:49
1

Your second question is easy:

.: .: is a directory

When you are running a Bash script and Bash encounters an error, it prints the name of the script and the line where the error was found, like so:

script.sh: line X: some message

The command line bash . something.sh attempts to run . as a script, and it thus fail. Maybe were you looking for bash ./script.sh? In that case, you don't need to specify the full path. Bash can find the script if you only do bash script.sh.

The output of your script is kind of strange:

: No such file or directorye/<my username>/<long path>

It is missing both the file information and part of the error message.

I'm guessing your script has some unintended unprintable characters. If this was written with an editor that uses CR-LF line terminators, you can import it with fromdos -b script.sh. The -b flag ensures that fromdos will leave a backup of your original file. If you are on Debian, you can install this program with the package tofrodos.

To verify whether you have unintended unprintable characters, use cat -A. Several interesting things may show up. For instance, TABs will print as ^I and newlines as $. If your file does have MS-DOS style line feeds, they will appear as ^M$.

0

Can you do following command and run it again ?

dos2unix script.sh

If still not working , remove non-printable letters from file using below command

tr -cd "[:print:]" script.sh > script2.sh bash script2.sh

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