Translate Shell使用

本文详细介绍了如何在Linux中使用命令行工具Trans进行翻译,包括安装、参数使用和语言代码查询。同时,文章讨论了在Java环境中调用Trans时可能遇到的问题,如异常流重定向、输入不全以及语言代码额外字符等,并提供了相应的解决方案和代码示例。通过这些实践,读者可以更好地理解和应用Trans,并在Java项目中实现命令行翻译功能。
摘要由CSDN通过智能技术生成

来源

Linux中使用命令行进行谷歌翻译, How To Use Google Translate From Commandline In Linux - Just Code

centos中安装

wget git.io/trans

chmod + x trans

sudo mv trans /usr/local/bin/ 

 使用

获得帮助

trans --help

重点参数

    -R, -reference-english 展示的language code作为 语种翻译的 -from和 -to的输入
        Print reference table of languages (in English names) and exit.

    -e ENGINE, -engine ENGINE
        Specify the translation engine to use.

    -b, -brief
        Brief mode.

    -d, -dictionary
        Dictionary mode.

    -s CODES, -sl CODES, -source CODES, -from CODES
        Specify the source language(s), joined by '+'.
    -t CODES, -tl CODES, -target CODES, -to CODES
        Specify the target language(s), joined by '+'.

-R列表

使用

翻译成指定语言

trans -t zh-CN "this is china that is china"

从指定语种翻译到指定语种

trans -t zh-CN -s en  "this is china that is china"

只输出翻译内容

trans -t zh-CN 'this is China'  -brief

语种识别

trans -id "this  is"

语种识别,只输出language code

trans -id "this  is" | grep "Code" | awk '{print $2}'

接下来,才是我关心的重点,我能不能用java自由调用这个工具,作为我的分析服务呢?

答案是,可以。

java调用trans踩的坑

1.异常流重定向至标准输入流。

来源

Runtime.getRuntime().exec踩坑总结(/bin/sh -c、异常流重定向)_你学废了吗?-CSDN博客1、exec(java.lang.String)`并不是想当然的是一个由命令+参数拼接的字符串。2、exec(java.lang.String[])`数组第一个元素是命令,从第二个元素起都是第一个元素命令的参数。3、可通过`/bin/sh -c`将一个多操作命令合并成一个完整命令执行,避免创建可执行脚本文件。4、用于控制进程的类`Process`,有三种I/O流管道,互相独立,管道空时不可读,满时不可写,遇到三个流管道中至少一个处于不可读写状态时,命令进程会阻塞等待。https://blog.csdn.net/weixin_36586120/article/details/111460543

某台服务器安装好trans后,没有测试trans的翻译功能,直接ping 8.8.8.8 能连外网,就开始直接用java调用 trans,始终没有结果返回且一直阻塞。java调用其他shell正常,于是怀疑是不是trans就是不能用,单独使用,果然不行。

该问题服务器 ping translate.googleapis.com 不通。最后排查发现是因为该服务器的nameserver=114.114.114.114 不是 8.8.8.8造成的。应该加一个。

那为什么错误没有返回呢,查看代码发现:

Process  process = Runtime.getRuntime().exec(sh)

应该用:

// redirectErrorStream = true 异常流重定向 2>&1

Process process = (new ProcessBuilder(cmds)).redirectErrorStream(true).start();

2.直接拼接shell命令造成输入不全

分析代码发现,Runtime.getRuntime().exec()有两种输入,一种是字符串,一种是字符串数组。

你如果用字符串,如果待翻译的内容中有空格,那么trans就只接收到了前面。

复现就是这样

所以构造命令时候最稳妥的是用数组输入:

String[] cmds = {"python", "/root/tmp/xxx.py", "xxx"};
Runtime.getRuntime().exec(cmds); 

3.获取的language code有额外不可见字符

看下面测试结果,trans获取的结果就是result code,用肉眼看没有其他字符,但是和en字符串比较,结果始终是false,于是将结果用 String code = UnicodeUtil.toUnicode(lang_code, false);转成unicode 和 ”en“转成的unicode发现,多了后面一串东西。

于是用replaceAll将结果清洗一下,和"en"比较,结果正常了

public static String getCode(String lang_result){
   return StrUtils.regexpExtract(lang_result,code_reg)
           .replace("[1m","")
           .replaceAll("\\u001b\\u005b\\u0032\\u0032\\u006d","") //注意结果有不可见字符串
           ;
}

初步分析是结果加粗造成的:

规范使用Process

1.用完以后注意关闭资源

input.close(); //关闭输入流
process.destroy(); // kill子进程

2.注意调用设置超时,不要阻塞主进程

来源:Process 执行shell 可设置超时_吉小样的博客-CSDN博客

process.waitFor(timeout, TimeUnit.MILLISECONDS) //1.7中没有,1.8以后才有

 3.如果希望错误结果能够返回,需要设置异常流重定向

// redirectErrorStream = true 异常流重定向 2>&1
 process = (new ProcessBuilder(sh)).redirectErrorStream(true).start();

 封装样例

  /**
     * 复杂的带传参的用这个
     * @param sh
     * @return
     */
    public static String exeShell(String[] sh,int timeout){
        Process process = null;
        BufferedReader input=null;
        List<String> processList = new ArrayList<String>();
        try {
//            process = Runtime.getRuntime().exec(sh);
            // redirectErrorStream = true 异常流重定向 2>&1
             process = (new ProcessBuilder(sh)).redirectErrorStream(true).start();
            if (process.waitFor(timeout, TimeUnit.MILLISECONDS)){//程序在限定时间内执行完毕
                /* 退出码为0时 属于正常退出**/
                if (process.exitValue() == 0){//执行shell出错 记录错误信息
                    input = new BufferedReader(new InputStreamReader(process.getInputStream()));
                    String line = "";
                    while ((line = input.readLine()) != null) {
                        processList.add(line);
                    }
                }
            }else {
                System.out.println("exe shell timeout ");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //关闭流
            if(input!=null){
                try {
                    input.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            //kill 子进程
            if(process!=null){
                process.destroy();
            }
        }
        String result = StringUtils.join(processList, "\n");
        return result;
    }

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值