2

换行符在 server2 (Solaris) 上被正确识别,而backslashn在 server1 (Linux) 上被视为字符。我该如何纠正?

在处理一个接受参数并发送邮件的简单脚本时,我首先注意到这种相当奇怪的行为..

句法:$ ksh SEND_MAIL.sh <to> <Subject> <body>

  1. 现在,当我在 server-1 上运行该脚本时

    [kent@server1] $ ksh SEND_MAIL.sh name@site.com "Subject" "123\n456" [Thu Jan 10 10:51:18 EST 2013] - 开始发送邮件到:name@site.com,带有主题\'>>>123\n456\'

    请注意,换行符被视为 backlash-n。

  2. 在 server-2 上,\n特殊字符正确扩展为换行符。

    [kent@server2] $ ksh SEND_MAIL.sh name@site.com "Subject" "123\n456" [Thu Jan 10 10:51:18 EST 2013] - 开始发送邮件到:name@site.com,带有主题\'>>>123 456\'

我想我可能需要更改一些 KornShell 环境变量,但我无法弄清楚。

更新:

在下面 Henk 的指导之后......我发现知道差异并不足以帮助我解决主要问题 - 即让 server1 上的脚本将\n字符识别为换行符。所以我改进了我的问题。


笔记:

Server1 是 Linux 服务器,而 Server2 是 Solaris。


环境详细信息 > KornShell: - 正如Henk Langeveld所建议的那样

在服务器 1 上:

[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

在服务器 2 上:

# 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

在服务器 1 和 2 上,我得到相同的行为

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

代码:

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

按照Oliver的建议,将该行set | grep SH放入两台服务器上的脚本中,以检查它正在运行的 shell 。

在服务器 1 上:

[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
...

在服务器 2 上:

[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
...
4

4 回答 4

2

看,在每台服务器上:

  • ksh的版本
  • 您在尝试时登录的 shell:grep kent /etc/passwd将在最后一个字段中显示登录 shell)。
  • 并做一个head -n 1 /path/to/SEND_MAIL.sh看看一个或另一个运动不同的“shebang”。
  • 最后,将该行set | grep SH放入另一个脚本中,比如说./test.sh,然后chmod +x ./test.sh,然后运行它 : ./test.sh: 以查看它是否在每个服务器中使用不同的 shell 运行
于 2013-01-10T18:45:59.050 回答
2

这是 AST ksh93、pdksh 还是较旧的 ksh88?

以下是如何ksh通过检查的输出ksh --version和值来检查你的版本${.sh.version}

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

然后告诉我们两台服务器上的结果是否相同。旧版本的 ksh 实际上可能会报告错误。


ksh93的解决方案:

在 server1 上,将您的 \n 嵌入到 ksh93Ansi string中,方法是将其括在$'and中'

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

这将推断出任何 C 风格的转义。

于 2013-01-11T00:30:24.787 回答
2

两台服务器有不同的ksh二进制文件。服务器 1 是来自 AT&T 的最新 ksh93,与大多数 linux 系统(debian 和 EL 衍生产品)捆绑在一起。服务器 2 是特立独行的。也许是这样pdksh?这解释了您所看到的差异。

在服务器 1 上:

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

在服务器 2 上:

# I'm am in bash
[kent@server2]$ ksh --version 
$
于 2013-01-11T08:47:35.037 回答
0

对于 Linux 上的 korn shell,请尝试使用 print 或 printf 而不是 echo。这对我行得通。我目前正在使用它将我的脚本从 AIX 移植到 Linux。我还没有测试所有可能的 contxt,但到目前为止它运行良好。我在此之前尝试过的另一种选择也是有效的:

在 .profile 之类的环境设置文件中,添加以下语句: export NL="" 在第一行输入 " 后,您应该按 ENTER 键,然后在新行的第一个列上再次按 "。

然后将所有 \n 替换为 ${NL},大括号是必需的,因为您不希望将 $NL 后面的内容视为 env var 名称的一部分。

祝你好运

于 2015-03-24T16:32:07.320 回答