如何更正shell脚本以识别运行Linux的另一台服务器上的换行符?

时间:2013-01-10 16:01:27

标签: shell scripting newline sftp ksh

在server1(Linux)上将新行字符正确识别,而在server1(Linux)上将其作为反斜杠 n 字符。我该如何纠正?

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

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

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

    [kent @ server1] $ ksh SEND_MAIL.sh name@site.com“Subject”“123 \ n456” [2013年1月10日10:51:18 2013] - 开始发送邮件至:name@site.com,     使用主题\'&gt;&gt;&gt; 123 \ n456 \'

    请注意,新行字符被视为反向间隙。

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

    [kent @ server2] $ ksh SEND_MAIL.sh name@site.com“Subject”“123 \ n456” [2013年1月10日10:51:18 2013] - 开始发送邮件至:name@site.com,     主题为''&gt;&gt;&gt; 123 456 \'

  3. 我想我可能需要更改一些KornShell环境变量,但我无法弄明白。

    更新

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


    备注:

      

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


    环境详细信息&gt; KornShell: - 正如 Henk Langeveld所建议

    在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
    

    在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
    

    在服务器1&amp; 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
    

    将行set | grep SH放在两台服务器上的脚本中,以检查它正在运行的shell,如下面建议的 Oliver

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

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

4 个答案:

答案 0 :(得分: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

答案 1 :(得分: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嵌入到ksh93 Ansi string中,将其封装在$''中:

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

这将推断任何C风格的逃脱。

答案 2 :(得分:2)

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

在server1上:

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

在server2上:

# I'm am in bash
[kent@server2]$ ksh --version 
$

答案 3 :(得分:0)

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

在某些env安装文件中,例如.profile,添加以下语句: export NL =“ “ 您应该在新行的第一行上键入“在第一行并再次点击”后按ENTER键。

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

祝你好运

相关问题