V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
hsuyeung
V2EX  ›  程序员

请教一个 ssh 连接服务器启动 jar 包字符集的问题

  •  
  •   hsuyeung · 2023-08-31 20:15:41 +08:00 via iPhone · 814 次点击
    这是一个创建于 452 天前的主题,其中的信息可能已经有所发展或是发生改变。

    事情的经过如下(手机发的格式略乱):

    1. 自己的博客之前都是本地 maven 打包后,再用 mobaxterm 远程连接阿里云服务器,执行 java -jar 命令来启动的。博客里有文件上传和读取的代码,在之前(一年多)都是正常没有任何问题的。21 号的时候用家里的新电脑更新了一些代码,把博客重新部署了一下,直接用 ssh 连接上去的。
    2. 前几天在公司没事的时候用公司的 windows 电脑上的 mobaxterm 连到 r 服务器上看了下最近的日志,发现出现了很多文件读取异常( No Such File Or Directory )。而且观察下来发现都是中文文件读取不到了。再看了下 nginx 日志,发现很多非正常的请求,我一开始还以为是服务器被攻击把我服务器上的文件给删了导致的。去看了下文件也全都还在,便开始找其他原因。
    3. 正好当时有另外一个 bug 需要修复,于是准备先把这个 bug 修复了再慢慢去看这个文件读取问题,结果,用公司电脑重新打包上传到服务器重新启动后,文件读取失败的问题消失了。
    4. 后来用家里新电脑打了个包上传到服务器部署,然后用 jinfo 命令查看启动信息,发现里面的 file.encoding 以及 shn.jnu.encoding 都不是 UTF-8 ,而是一个叫做 ansi_x3.4-1968 的字符集。然后用公司电脑上传部署,再用 jinfo 查看,字符集就全是 UTF-8 了。
    5. 于是问题也就确定了,以前上传文件的时候是 UTF-8 编码的,现在字符集变了也就导致读取文件时找不到原来的文件了。
    6. 经过一番搜索后,有一篇文章提到了是因为 ssh 客户端的字符集不同导致的,大概意思就是 jar 包启动的时候读取的环境变量取决于 ssh 客户端。于是我也验证了一下,把家里电脑设置了环境变量

    export LANG=en_US.UTF-8

    export LC_ALL=en_US.UTF-8

    然后重新 ssh 连接服务器重新启动 jar 包,文件读取失败的问题就消失了,jinfo 查看字符集也变成 UTF-8 了。


    问题找到了,最好的解决办法就是启动的时候自己手动指定字符集。但是我还是没想明白,为什么启动的时候读取的是我 ssh 客户端的环境变量配置,而不是我的服务器本机配置呢?

    6 条回复    2023-09-01 18:07:27 +08:00
    hsuyeung
        1
    hsuyeung  
    OP
       2023-08-31 20:19:41 +08:00 via iPhone
    至于为什么会出现 ansi_x3.4-1968 这个字符集,当时网上搜了一圈就是因为读取不到字符集的环境变量时就会默认用这个。我用家里的新电脑把之前配置的字符集环境变量删掉之后,执行 locale charmap 命令,确实打印出来就是 ansi_x3.4-1968
    cnhongwei
        2
    cnhongwei  
       2023-08-31 22:14:18 +08:00   ❤️ 1
    linux 是进程继承父进程的环境。你使用 shell 启动,当然会使用你当前 shell 的字符集。你可以设置 shell 的字符集,也可以使用服务的方式启动,也可以在启动命令中强制设置字符集。
    hsuyeung
        3
    hsuyeung  
    OP
       2023-08-31 22:57:23 +08:00 via iPhone
    @cnhongwei 原来如此,感谢~
    qfdk
        4
    qfdk  
       2023-09-01 10:25:56 +08:00 via iPhone
    其实也可以加到.bashrc 里面
    hsuyeung
        5
    hsuyeung  
    OP
       2023-09-01 11:11:23 +08:00
    @qfdk 是的,这个我在家里电脑上已经配置了。主要是当时不理解为什么启动的时候使用的是我 ssh 客户端的环境变量而不是服务器本机的
    julyclyde
        6
    julyclyde  
       2023-09-01 18:07:27 +08:00
    ssh 客户端会 SendEnv ;而 sshd 那边会 AcceptEnv
    所以就影响了在其中运行的进程了

    你能认识到“最好的解决办法就是启动的时候自己手动”已经超过了绝大多数 javaer 了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1004 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 21:36 · PVG 05:36 · LAX 13:36 · JFK 16:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.