2

The new-line character is correctly recognized on server2 (Solaris) while it is taken as a backslashn character on server1 (Linux). How do I correct this?

While working on a simple script that accepts arguments and sends out mails I first noticed this rather odd behavior..

Syntax: $ ksh SEND_MAIL.sh <to> <Subject> <body>

  1. Now when I run that script on server-1

    [kent@server1] $ ksh SEND_MAIL.sh name@site.com "Subject" "123\n456" [Thu Jan 10 10:51:18 EST 2013] - Starting to send mail to: name@site.com, with the subject \'>>>123\n456\'

    Notice that the new-line character is taken as backlash-n.

  2. While on server-2 the \n special character correctly expands to a new-line character.

    [kent@server2] $ ksh SEND_MAIL.sh name@site.com "Subject" "123\n456" [Thu Jan 10 10:51:18 EST 2013] - Starting to send mail to: name@site.com, with the subject \'>>>123 456\'

I think I may need to change some KornShell environment variables but I can not figure it out.

UPDATE:

After Henk's guidance below... I see that knowing the difference is not enough in helping me solve main issue - that is to have the script on server1 recognize the \n characters as a new-line. So I have improved my question.


Notes:

Server1 is a Linux server, while Server2 is Solaris.


Environment details > KornShell: - As suggested by Henk Langeveld

On server1:

[kent@server1]$ ksh --version
  version         sh (AT&T Research) 93t+ 2010-02-02
[kent@server1]$ echo ${.sh.version}
bash: ${.sh.version}: bad substitution
[kent@server1]$ [ "${ERRNO}" ] && echo ksh88 || echo ksh93
ksh93
[kent@server1]$ [ "`echo "\c" | grep c`" ] && echo ksh93 || echo ksh88 
ksh93

On server2:

# I'm am in bash
[kent@server2]$ ksh --version 
$
$ ksh --version
$ 
[kent@server2]$ echo ${.sh.version}
bash: ${.sh.version}: bad substitution
[kent@server2]$ [ "${ERRNO}" ] && echo ksh88 || echo ksh93
ksh93
[kent@server2]$ [ "`echo "\c" | grep c`" ] && echo ksh93 || echo ksh88 
ksh93

On server 1 & 2 I get the same behavior:

$ echo -e "1\n2"
1
2
$ echo "1\n2"
1\n2
$ echo $'1\n2'
1
2

Code:

SEND_MAIL.sh

#Syntax: $ ksh SEND_MAIL.sh <to> <Subject> <body>
TO_REC=$1
SUBJECT=$2
MESSAGE=$3
echo "$MESSAGE"| mailx -s "$SUBJECT" $TO_REC

Putting the line set | grep SH in the script on both the servers to check the shell it is running on as Oliver suggested below.

On server1:

[kent@server1]$ ksh SEND_MAIL.sh kent@123.com "Subject" ">>>123\n\n456$a"
KSH_VERSION=.sh.version
SHELL=/bin/bash
SHLVL=3
SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass
SSH_CLIENT='3.209.100.144 59645 22'
SSH_CONNECTION='3.209.100.144 59645 3.56.9.127 22'
SSH_TTY=/dev/pts/1
...

On server2:

[kent@server2]$ ksh SEND_MAIL.sh kent@123.com "Subject" ">123\n\n456$a"
SHELL=/bin/ksh
SHLVL=1
SSH_CLIENT='3.209.100.144 49351 22'
SSH_CONNECTION='3.209.100.144 49351 3.56.29.159 22'
SSH_TTY=/dev/pts/2
...
javaPlease42
  • 4,699
  • 7
  • 36
  • 65
Kent Pawar
  • 2,378
  • 2
  • 29
  • 42
  • 2
    The script may have nothing to do with it. Do you have the same behaviour when passing your string to a simple unix command (like `echo`)? – Khaur Jan 10 '13 at 16:07
  • larsmans - I added the code. @Khaur - Pls see the 'behavior' section above.. Thanks – Kent Pawar Jan 11 '13 at 03:23

4 Answers4

2

see, on each server:

  • the version of ksh
  • which shell you logged in when when trying: grep kent /etc/passwd will show the login shell in the last field).
  • And do a head -n 1 /path/to/SEND_MAIL.sh to see if one or the other sports a different "shebang".
  • And finally, put the line set | grep SH in another script, say ./test.sh, and then chmod +x ./test.sh , and run it : ./test.sh : to see if it is run with a different shell in each server
Olivier Dulac
  • 3,695
  • 16
  • 31
  • 1
    The shebang will make no difference: the scripts are being invoked explicitly using ksh. The shebang only makes a difference if you're executing a script directly. – me_and Jan 10 '13 at 20:15
  • Hi Olivier, the code is identical so shebang is not the issue.. Pls see my post, I have updated it with the output. Also `grep kent /etc/passwd` doesn't work as we are using LDAP so my account is not in /etc/passwd.. I am not too familiar with this.. – Kent Pawar Jan 11 '13 at 03:33
2

Is this AST ksh93, pdksh, or an older ksh88?

Here's how you can check the version of your ksh by checking the output of ksh --version and the value of ${.sh.version}

$ ksh --version
version         sh (AT&T Research) 93u+ 2012-06-26
$ ksh -c 'echo ${.sh.version}'
Version AJM 93u+ 2012-06-26

Then tell us if the results are the same on the two servers. Older versions of ksh may actually report an error.


Solution for ksh93:

On server1, embed your \n in a ksh93 Ansi string, by enclosing it in $' and ':

two_lines=$'one\ntwo'  && print "$two_lines"
one
two

This will extrapolate any C-style escapes.

Henk Langeveld
  • 8,088
  • 1
  • 43
  • 57
  • I updated my post with the outputs.. They both seem to be running the same version of korn shell. – Kent Pawar Jan 11 '13 at 03:24
  • Minor edit to assure that the echo ${.sh.version} is actually performed by ksh. Your servers run different shells, as explained in my follow-up answer. I tried to merge that in here, but that got messy. – 11 hours ago *fixed typo* – Henk Langeveld Jan 11 '13 at 20:43
  • The problem with ANSI strings is that it would allow you to use UNIX variables inside them.. So how do I get the newline character and also have the UNIX variables to expand correctly ? – Kent Pawar Jan 21 '13 at 07:22
  • 1
    Hi Kent, create shell constants for the special characters using ANSI strings (`NL=$'\n'`). Then concatenate all of them in a double quoted string ( `message="$line_one${NL}$line_two"` ) – Henk Langeveld Jan 21 '13 at 19:51
  • Thanks @Henk, I will do that. I appreciate your guidance with this problem. – Kent Pawar Jan 22 '13 at 10:49
2

The two servers have different ksh binaries. Server 1 is the most recent ksh93 from AT&T as bundled with most linux systems (debian and EL derivatives). Server 2 is a maverick. Perhaps that's pdksh? This explains the differences you're seeing.

On server1:

[kent@server1]$ ksh --version
  version         sh (AT&T Research) 93t+ 2010-02-02

On server2:

# I'm am in bash
[kent@server2]$ ksh --version 
$
Henk Langeveld
  • 8,088
  • 1
  • 43
  • 57
0

For korn shell on Linux, try print or printf instead of echo. That works for me. I am currently using it to port my scripts from AIX to Linux.I have not tested all possible contxts, but so far it has been working well. Another option, which I tried prior to this, which also works is this:

In some env setup file like .profile, add this statement: export NL=" " You should hit the ENTER key after typing " on the first line and hit " again on the very firts column on the new line.

Then replace all \n with ${NL}, the curly braces are required since you do not want what follows $NL to be treated as part of the env var name.

Good luck