echo printing variables on single line - bash

I have two variables:
export portNumber=8888^M
export loginIP_BASE=10.1.172.2^M
I'm trying to print them both on a single line separated by a colon ':'. It should look like "10.1.172.2:8888"
echo -n 'Login IP:'
echo -n $loginIP_BASE
echo -n ':'
echo $portNumber
but it it prints this instead:
:8888 IP:10.1.172.2
Why is it doing that? How can I get it to do what I want?
Also, the variables are preexisting from another file, so I did not write them myself. What does the "^M" do?

In Windows a tipical new line is \r\n (in *nix systems is just \n).
\r is carriage return.
\n is new line.
^M is \r, so after writing $loginIP_BASE you are at position 0 of the actual line.
If you want to remove all those ^M you can do it in vim o with sed using:
sed s/{ctrl+v}{ctrl+m}// file > new_file
({Ctrl+v} means press ctrl and then v)

The file has been transferred from Windows in binary mode, and still has carriage return characters at the ends of the lines.
They are your ^M symbols, and they are causing the text position to return to the start of the line when the values are displayed - the carriage return at the end of the first value makes the second value display at the start of the line again, overwriting part of the first value.
The right fix is to transfer the file from Windows using text mode transfer, or to run dos2unix on the file after you've transferred it. (Or if the file isn't going to be transferred from Windows again, just delete the ^M characters!)

Use dos2unix command:
dos2unix filename
One more trick to remove Ctrl+M in vi editor:
:%s/^V^M//g

Related

Using SED in a shell script

I have two issues that I am seeking help with. I am using Cygwin and a Unix newbie.
1) I have a shell script that executes SED command. In my script called master.sh, I have the following
sed -nrf remove.sed < code.tp4 > code.tp5
remove.sed has one line
/ INCLUDE /d
When I execute the script via the following command
bash master.sh
I get the following error
master.sh: line 12: $'\r':command not found
I have no clue on what is throwing this error.
2) My 2nd issue is that the output file "code.tp5" ends up "code.tp5?". However, using Windows explorer, the question mark appears to be
unprintable characters. The most confusing part of this is that I get no errors when I execute this via the command prompt. Any assistance would be appreciated.
You could try:
sed -nr s/\r//;/ INCLUDE /d' < code.tp4 > code.tp5; sed 's/$/\r$/' code.tp5
The command 's' is for substitution. '\r' carriage return. So s/\r// will replace carriage return to nothing. After that you will remove the lines that contains the pattern '/ INCLUDE /d'. And with this: sed 's/$/\r$/' code.tp5 finally you will add again the carriage return so will became again a DOS text file ($ means end of line on a regular expression) . (Unix line endings are only new line, and DOS cas carriage return and newline).

Lines ending with ^M in my config files on Ubuntu?

In my bash script, I am trying to change a configuration line one of my configuration file.
here is the bash script I used.
#!/bin/bash
jdbcURL(){
ssh ppuser#10.101.5.84 "sed -i \"s|\(\"jdbc.url\" *= *\).*|\1$2|\" $1"
}
jdbcURL $4 $5
After running this script, the configuration file is changed but the problem is, every lines in the configuration file is ending with ^M , so anything wrong in my bash script? Hope anyone help me. Thank You.
The ^M character is a carriage return - an extra character that Windows appends to newlines. It is usually rendered as \r. ^M is another visual representation.
You can strip them with the dos2unix utility:
$ dos2unix myfile
For reference, *nix operating systems (including OSX) use \n to delimit lines; Windows uses \r\n. Mac operating systems, up to OS-9 used \r alone.
You're encountering an issue with different line termination between Unixoid and Windoid worlds. Where Unix and consorts use a single 0x0a (linefeed) character, microsoft's world prefers 0x0d 0x0a (carriage return, linefeed). So if there is a file with lines ending with both carriage return AND linefeed looked at with unixoids, it interprets the linefeed as line terminator, and leaves the carriage return as part of the line, This is what you see as ^M
Conversion utilities to convert line terminators between these different conventions exist, but you ought to be able to let your sed expression take care of it.
As side note, Apple used to use another representation of line end, namely a single carriage return. I don't know whether they still do.

: command not foundop/dominio.sh: line 2:

I'm writing shell scripting for Mac.
Here's my script:
echo "Bienvenido";
/Applications/sdk/platform-tools/adb devices;
sudo /Applications/sdk/platform-tools/adb shell input text 'sp.soporte#gmail.com';
It realize the correct operation, but here is the output :
$ /Users/julien/Desktop/dominio.sh
Bienvenido
: command not foundop/dominio.sh: line 1:
List of devices attached
4790057be1803096 device
: command not foundop/dominio.sh: line 2:
: command not foundop/dominio.sh: line 3:
julien$
If I erase the ; it's not working any more. How should I do????
I think you have Windows-style line endings in your script.
Unix-like systems, including MacOS, use a single LF character to terminate a line; Windows uses a CR-LF pair.
A Windows-style text file looks, on a Unix-like system, like ordinary text with an extra CR character at the end of each line.
Since you have a semicolon at the end of each line, this line:
echo "Bienvenido";
appears to the shell as two commands: echo "Bienvenido" and the CR character (which could actually be a command name if it existed). Note that the echo command was executed.
The shell prints an error message, something like:
/path/to/script: 1: CR: command not found
except that it prints the actual CR (carriage return) character, which moves the cursor to the beginning of the current line, overwriting part of the error message.
Translate your script to use Unix-style line endings. You can use dos2unix for this if you have it. (Read the man page; unlike most filter programs, it overwrites its input file by default.)
Incidentally, you don't need a semicolon on the end of each line of a shell script. Semicolons are needed only when you have multiple commands on one line.
Also, you should probably have a "shebang" as the first line of your script, either #!/bin/sh or #!/bin/bash (use the latter if your script uses bash-specific features).

Bash programmation (Cygwin): Illegal Character ^M [duplicate]

This question already has answers here:
Are shell scripts sensitive to encoding and line endings?
(14 answers)
Closed 3 years ago.
I have a problem with a character. I think it's a conversion problem between dos and unix.
I have a variable that is a float value.
When I print it with the echo command i get:
0.495959
But when I try to make an operation on that value with the bc command (I am not sure how to write the bc command).
echo $mean *1000 |bc
I get:
(standard_in) 1 : illegal character: ^M
I already use the dos2unix command on my .sh file.
I think it's because my variable have the ^M character (not printed with the echo command)
How can i eliminate this error?
I don't have Cygwin handy, but in regular Bash, you can use the tr -d command to strip out specified characters, and you can use the $'...' notation to specify weird characters in a command-line argument (it's like a normal single-quoted string, except that it supports C/Java/Perl/etc.-like escape sequences). So, this:
echo "$mean" * 1000 | tr -d $'\r' | bc
will strip out carriage-returns on the way from echo to bc.
You might actually want to run this:
mean=$(echo "$mean" | tr -d $'\r')
which will modify $mean to strip out any carriage-returns inside, and then you won't have to worry about it in later commands that use it.
(Though it's also worth taking a look at the code that sets $mean to begin with. How does $mean end up having a carriage-return in it, anyway? Maybe you can fix that.)
This works:
${mean/^M/}
You can get ^M by typing Ctrl-V followed by Ctrl-M. Or, alternatively:
${mean/$(printf "\r")/}
The benefit of this method compared to #ruakh's is that here you are using bash built-ins only. The first will be faster as the second will run inside a subshell.
If you just want to "unixize" $mean:
mean="${mean/^M/}"
Edit: There's yet another way:
${mean/$'\r'/}
Running Windows stuff in cygwin has one nasty side-effect as you found out - capturing the output of Windows programs in a cygwin bash variable will also capture the CR output by the program.
Judicious use of d2u avoids the issue - for example,
runtime="`mediainfo --Inform='Video;%Duration%' ${movie} | d2u`"
(Without the d2u, ${runtime} would have a CR tacked on the end, which causes the problem you saw when you feed it to 'bc' for example.)
Maybe you should just save your script in UNIX format instead of DOS.
Try this:
echo `echo $mean` *1000 |bc
If echo really isn't printing it, it should work.
^M is a carriage return character that is used in Windows along with newline (\n) character to indicate next line. However, it is not how it is done in UNIX world, and so bash doesn't treat at as a special character and it breaks the syntax. What you need to do is to remove that character using one of many methods. dos2unix tool can come handy, for example.
As others have pointed out, this is a Windows line ending issue. There are many ways to fix the problem, but the question is why did this happen in the first place.
I can see this happening in several places:
This is a WINDOWS environment variable that was set when Cygwin started up. Sometimes these variables get a CRLF on the end of them. You mentioned this was a particular issue with this one variable, but you didn't specify where it was set.
You edited this file using a Windows text editor like Notepad or Winpad.
Never use a text editor to edit a program. Use a program editor. If you like VI, download VIM which is available on Windows and comes on Cygwin (and all other Unix-based platforms). If VIM isn't for you, try the more graphically based Notepad++. Both of these editors handle end of line issues, and can create scripts with Unix line endings in Windows or files with Windows line endings in Cygwin.
If you use VIM, you can do the following to change line endings and to set them:
To see the line ending in the current file, type :set ff? while in command mode.
To set the line ending for Unix, type :set ff=unix while in command mode.
To set the line ending for Windows, type :set ff=dos while in command mode.
If you use Notepad++
You can go into the Edit-->EOL Conversion menu item and see what your current line ending setting (it's the one not highlighted) and change it.
To have Notepad++ use Unix line endings as the default, go into the Settings-->Preferences menu item. In the Dialog box, select the New Document/Default Directory tab. In the Format section which is part of the New Document section, select the line ending you want. WARNING: Do not select Mac as an option. That doesn't even work on Macs. If you have a Mac, select Unix.

How to create the empty 'Icon\r' file for a .dmg from shell script?

From shell script, I would like to create the empty 'Icon\r' file for a Mac OS X disk image (dmg), so as the .VolumeIcon.icns icon file is taken into account by the finder; the damn '\r' character is not accepted from the console:
touch Icon\r
ls Icon*
> Iconr
and other things happen when trying to type 'Icon\r', "Icon\r" etc., I can't achieve to make it accept "\r" as the typical carriage return required at the end of the file name.
Any idea how to type it?
Thanks
I assume the file name should be five characters, the last one being a carriage return. In bash or zsh:
touch $'Icon\r'
Or you can type the carriage return in the shell: touch Icon Ctrl+V Ctrl+M Enter .
echo -e "Icon\\r" | xargs touch
In bash, you can open your quotes and type "Icon, then on the following line (your prompt should be a > character) close the quotes.

Resources