linuxscriptingksh

ksh "." operator is doing string replacement instead of concatenation


I was debugging a script in which I found the following weird behavior. The script is simply setting some variables by sourcing another file, then the values of these variables are used to run the main script command.

The first file has the following line:

export PROJECT=ABCD1234

The script then sources this file thought the following line:

. file_path

Later in the script, the script is using the $PROJECT variable in the following statement:

cd $PROJECT.proj #expecting to do string concatenation

The problem here is that $PROJECT.proj doesn't result in "ABCD1234.proj", actually it does string replacement instead of string concatenation, so $PROJECT.proj equals .proj234!!

I suspected that there might be some special hidden characters in the first file that cause this behavior, so I rewrote the file using gvim instead of nedit & it worked.

Does anybody have any idea how this happened??


Solution

  • Anytime you are creating files on Windows and then moving or using them on a Unix/Linux like environment, be sure to convert your files so they work properly on unix/linux.

    Use the dos2unix utility for this, i.e.

      dos2unix file [file1 file2 file3 .... myFile*]
    

    As many files as will fit on the cmd line.


    Disappearing characters like

    ABCD1234.proj
    

    but getting some, but not all, like

    proj234
    

    Are often the result of the Windows line-ending characters conflicting with Unix/Linux line-ending character. Windows uses ^M^J (\r\n), where as unix/linux uses just ^J (\n).

    OR

    Ctrl   oct     hex     dec   abbrev
    ^J     012     0a      10    nl
    ^M     015     od      13    cr
    

    cr = Carriage Return

    Think of the old typewriters, it is a two step process.

    The lever both moves the platen back to the left margin AND it advances the paper so the next line will be typed on. CR returns the carriage to the left margin, will new-line advances the printing to the next line.

    Unix assumes there is an implied CR with an NL, so having a CR confuses things and makes it easy for your system to overwrite data (or maybe it just the display of data, I don't have time to test right now).

    IHTH