Reputation: 501
I have following snippet:
host="https://example.com"
port="80"
url="${host}:${port}"
echo $url
the output is:
:80ps://example.com
How can I escape the colon here. I also tried:
url="${host}\:${port}"
but it did not work. Expected output is:
https://example.com:80
Upvotes: 3
Views: 4495
Reputation: 3388
You've most likely run into what I call the Linefeed-Limbo. If I copy the code you provided from StackOverflow and run it on my machine (bash version 4.4.19(1)), then it outputs correctly
user@host:~$ cat script.sh
host="https://example.com"
port="80"
url="${host}:${port}"
echo $url
user@host:~$ bash script.sh
https://example.com:80
Different operating systems use different ASCII symbols to represent when a new line occurs in a text, such as a script. This Wikipedia article gives a good introduction.
As you can see, Unix and Unix-like systems use the single character \n
, also called a "Line Feed". Windows, as well as other systems, use \r\n
, so a "carriage return" followed by a "line feed".
What happens now is when you write a script on Windows on an editor such as notepad, what you write is host="example.com"\r\n
. When you copy this file into Linux, Linux interprets the \r
as if it were part of the script, since only \n
is considered a new line. And indeed, when I change my newline style to DOS-style, I get the exact output you get.
You have several options to fix this issue.
dos2unix
)Since all you need to do is replacing every instance of \r\n
with \n
, you could use any text-editing software you want. However, if you like simple solutions, then dos2unix
(and its sister unix2dos
) might be what you looking for:
user@host:~$ dos2unix script.sh
dos2unix: converting file script.sh to Unix format...
That's it. Run your file now and you will see it behaves well.
By using a more advanced text editor such as Notepad++, you can define which style of newline you would like to use.
By changing the newline-type to whichever system you intend to run your script on, you will not run into any problems like this anymore.
:80ps://example.com
?To understand why your output is like this, you have to look at what your script is doing, and what \r
means.
Try thinking of your terminal as an old-fashioned typewriter. Returning the carriage means you start writing on the left again. Making a "new line" means sliding the paper. These two things are seperate, and I think that's why some systems decided to use these two characters as a logical "new line".
But I digress. Let's look at the first line, host="https://example.com"\r
.
What this means when printed is "Print https://example.com, then put the carriage back at the start". When you then print :80\r
, it doesn't start after ".com", it starts at the beginning of the line, because that's where you (unknowingly) told the cursor to go. it then overwites the first few characters, resulting in ":80ps://example.com" to be written. Keep in mind that after 80, you again placed a carriage return symbol, so any new text you would have written ends up overwriting the beginning again.
Upvotes: 4
Reputation: 133710
It works for me, try to remove carriage returns in variables and then try.
new_host=$(echo "$host" | tr -d '\r')
new_port=$(echo "$port" | tr -d '\r')
new_url="${new_host}:${new_port}"
Upvotes: 2