老哥们我有一个在 Linux 执行 Java Process 的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
DIO
V2EX    程序员

老哥们我有一个在 Linux 执行 Java Process 的问题

  •  
  •   DIO 2023 年 5 月 25 日 2769 次点击
    这是一个创建于 963 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我想将类似 ffmpeg -i “input.mkv” -i “input.chs&jpn.ass” -c copy "output/output1.mkv" 这样的命令由 Java 代码来执行

    java

     List<String> command = new ArrayList<>(); command.add(ffmpegPath); command.add("-i"); //输入视频文件 File command.add(file.getAbsolutePath()); command.add("-i"); //输入字幕文件 File command.add(sub.getAbsolutePath()); command.add("-c"); command.add("copy"); //拼接输出路径 command.add((new File(out,fileName)).getAbsolutePath()); 

    由于考虑多平台运行,所以路径获取和拼接都是通过 File ,没有自己加 Separate 。

    在 windows 编译执行没问题,成功进行了分类

    win 演示 1

    win 演示 2

    但是在 linux,总是执行失败

    Log 以后,提示是这样的:

    INFO: "/home/codeTest/ffmpegSubTest/[Kamigami&VCB-Studio] Boku dake ga Inai Machi [01][Ma10p_1080p][x265_flac_ac3].mkv": No such file or directory linux 其实已经分好类了,也就是说 File 对象指向是符合我预期的,只是创建文件夹利用的是 Java File 类的 mkdirs ()。

    那就是 ffmpeg 命令这里参数出了问题,我试过给参数再套一层双引号(""),同样是 win 编译执行 ok ,linux “No such file or directory”

    请问如何处理参数问题,或者有更好的解决方案希望能赐教

    java Process 在不同平台执行看了会源码没看太明白。

    第 1 条附言    2023 年 5 月 26 日

    老哥们这是我的代码,写的有点粗糙,轻喷。 点击访问代码

    额外需要的依赖这里下载 https://commons.apache.org/proper/commons-io/download_io.cgi

    第 2 条附言    2023 年 5 月 26 日
    问题解决了,谢谢大家
    23 条回复    2023-05-26 10:46:57 +08:00
    urnoob
        1
    urnoob  
       2023 年 5 月 25 日 via Android
    文件名包含空格导致的吧
    判断下平台,Linux 就给空格加转义
    urnoob
        2
    urnoob  
       2023 年 5 月 25 日 via Android
    或者把文件名用双引号包起来
    CLMan
        3
    CLMan  
       2023 年 5 月 26 日
    文件没找到就是特殊字符的原因,先一个个测试是否哪些字符导致的问题,在想办法从程序上,还是从修改文件名上解决问题。
    DIO
        4
    DIO  
    OP
       2023 年 5 月 26 日 via Android
    @urnoob 双引号包起来亲测不可行,命令行直接用是奏效的。如果不用双引号包起来,命令行直接执行时就是割裂的。平台判断也加了。转义之前没尝试,因为不知道空格转义成什么,也不知道有没有什么其他字符需要处理。
    msg7086
        5
    msg7086  
       2023 年 5 月 26 日
    很高兴见到你下载我组作品。
    建议你先把 command 的内容打印出来看看是不是符合预期。

    “/home/codeTest/ffmpegSubTest/[Kamigami&VCB-Studio] Boku dake ga Inai Machi [01][Ma10p_1080p][x265_flac_ac3].mkv” 这个文件真实存在吗?

    双引号应该是不需要套的。
    DIO
        6
    DIO  
    OP
       2023 年 5 月 26 日 via Android
    @msg7086 贵组字幕做的很好,其他有直接内嵌的但是翻译太差不想用于是想搞个工具 233 。command 在平台执行的具体内容可以打印出来吗,我在 ide 调试看不到转换后的内容。由于能力有限,查看源码也没搞清楚。
    msg7086
        7
    msg7086  
       2023 年 5 月 26 日
    @DIO 直接执行命令是不会被转义的,只有经过 shell 运行的时候才需要考虑转义(和双引号等 shell 会处理的符号)。
    所以不存在转换后的内容一说,你填在 command 里的参数就是实际执行的参数。
    DIO
        8
    DIO  
    OP
       2023 年 5 月 26 日 via Android
    @msg7086 文件是真实存在的,我的代码都是自动从当前目录扫描得到 file 的,我其实不会去手动输入任何路径。双引号我在参数里套过,但是照样是 win 符合预期执行,linux 不符合。相同的命令形式在两个平台测试,却是都能达到预期效果
    DIO
        9
    DIO  
    OP
       2023 年 5 月 26 日 via Android
    @msg7086 如果说是按照数组形式,命令是否符合预期,是的,我在 LOG 以及 IDE 调试时都会查看 command 数组内容,参数均与预期一致
    msg7086
        10
    msg7086  
       2023 年 5 月 26 日
    你贴的错误日志应该是从 logger 输出的吧。logger.info()里的参数你填的是什么?以及有没有抓到任何 exception ?
    ysc3839
        11
    ysc3839  
       2023 年 5 月 26 日 via Android
    @urnoob 你说 Windows 出错了这么做还有点道理。Windows 和 Unix 有个显著差异是,Windows 的进程命令行是一个字符串,而 Unix 的进程命令行是字符串数组。既然 Windows 只能传单个字符串,这其中就涉及空格转义问题了。理论上 Windows 程序可以用任意规则解析命令行,不过为了兼容 Unix ,是有提供一套标准的解析规则来解析成字符串数组的。而 Unix 进程拿到的就是字符串数组,解析工作是由 shell 进行的。如果是自己程序启动进程,那可以直接传递字符串数组,不需要转义。

    至于楼主的问题,我比较怀疑是命令行写错了,建议给出一段最简单的可复现代码。
    githmb
        12
    githmb  
       2023 年 5 月 26 日
    你是不是忽略了 & 在 Linux 下的作用?
    ETiV
        13
    ETiV  
       2023 年 5 月 26 日 via iPhone
    恰恰是最关键的 [用什么去执行命令] 的代码没给出来
    cslive
        14
    cslive  
       2023 年 5 月 26 日
    文件名有空格,在 linux 下识别不出来,将空格替换成下划线就可以了
    DIO
        15
    DIO  
    OP
       2023 年 5 月 26 日
    @msg7086
    ## 我是简单把 list 转成字符串了

    `code`
    ```
    BindingContextFactory.LOGGER.info("command is"+command.toString());
    ```

    'res'
    ```
    INFO: command is[ffmpeg, -i, "/home/codeTest/ffmpegSubTest/[Kamigami&VCB-Studio] Boku dake ga Inai Machi [01][Ma10p_1080p][x265_flac_ac3].mkv", -i, "/home/codeTest/ffmpegSubTest/[Kamigami&VCB-Studio] Boku dake ga Inai Machi [01][Ma10p_1080p][x265_flac_ac3].jpn.ass", -c, copy, "/home/codeTest/ffmpegSubTest/output/jpn/[Kamigami&VCB-Studio] Boku dake ga Inai Machi [01][Ma10p_1080p][x265_flac_ac3].mkv"]
    ```

    ## 另外就是简单的把 process 的流输出出来,能简单看到命令执行反馈
    ```
    try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
    String line = null;
    while ((line = bufferedReader.readLine()) != null) {

    BindingContextFactory.LOGGER.info(line);
    }
    } catch (IOException e) {
    }
    }).start();
    ```

    ## 然后 Exception 好像没有抓取到
    DIO
        16
    DIO  
    OP
       2023 年 5 月 26 日
    @ysc3839 您好。我的代码已经 append 贴出。谢谢您
    DIO
        17
    DIO  
    OP
       2023 年 5 月 26 日
    @ETiV

    您好。我的代码已经 append 贴出。谢谢您
    DIO
        18
    DIO  
    OP
       2023 年 5 月 26 日
    @githmb 我注意到 linux 目录下,带有&符号的目录会带单引号'',于是我尝试了判断系统类型,windows 加双引号或者不带,其他加单引号传参。还是 No such file or directory 。

    接下来我会尝试转义&字符
    感谢您,我在 append 中贴出代码链接,您什么时候有空希望能指教一二
    yazinnnn
        19
    yazinnnn  
       2023 年 5 月 26 日
    val command =
    ProcessBuilder(
    "ffmpeg",
    "-i",
    "/home/yazi/Downloads/[20230402]ん YuuRi Cas\uD83E\uDD40.mp4",
    "/home/yazi/Downloads/output.mp4"
    ).command()
    println(command)
    val process = Runtime.getRuntime().exec(command.toTypedArray())

    用这个命令试了一下, 可以正常执行, 是不是你路径写错了?
    msg7086
        20
    msg7086  
       2023 年 5 月 26 日
    @DIO #15

    [ffmpeg, -i, "/home/codeTest/ffmpegSubTest/[Kamigami&VCB-Studio] Boku dake ga Inai Machi [01][Ma10p_1080p][x265_flac_ac3].mkv", -i, "/home/codeTest/ffmpegSubTest/[Kamigami&VCB-Studio] Boku dake ga Inai Machi [01][Ma10p_1080p][x265_flac_ac3].jpn.ass", -c, copy, "/home/codeTest/ffmpegSubTest/output/jpn/[Kamigami&VCB-Studio] Boku dake ga Inai Machi [01][Ma10p_1080p][x265_flac_ac3].mkv"]

    双引号都删掉试试呢

    [ffmpeg, -i, /home/codeTest/ffmpegSubTest/[Kamigami&VCB-Studio] Boku dake ga Inai Machi [01][Ma10p_1080p][x265_flac_ac3].mkv, -i, /home/codeTest/ffmpegSubTest/[Kamigami&VCB-Studio] Boku dake ga Inai Machi [01][Ma10p_1080p][x265_flac_ac3].jpn.ass, -c, copy, /home/codeTest/ffmpegSubTest/output/jpn/[Kamigami&VCB-Studio] Boku dake ga Inai Machi [01][Ma10p_1080p][x265_flac_ac3].mkv]

    变成这样应该就对了。
    msg7086
        21
    msg7086  
       2023 年 5 月 26 日
    Linux 下,Shell 才是负责转义的,包括空格,&,[],等等,都只有在经过 Shell 的时候(比如 bash -c ,或者在命令行提示符下运行时)。

    直接从 Java 调用 syscall 运行的时候加双引号是错误的行为。

    我想这也是为什么你一开始的提示里

    "/home/codeTest/ffmpegSubTest/[Kamigami&VCB-Studio] Boku dake ga Inai Machi [01][Ma10p_1080p][x265_flac_ac3].mkv": No such file or directory

    会有双引号的原因。因为你这样写的话就是要寻找 [.] / ["] / [home] 这个目录了。
    DIO
        22
    DIO  
    OP
       2023 年 5 月 26 日
    @msg7086 感谢您,他好像开始工作了。昨天可能是头疼所以把转义字符去掉以后忘记修改代码到 NAS 。
    loginv2
        23
    loginv2  
       2023 年 5 月 26 日
    简化输入文件名 使用绝对目录定位。我记得 ffmpeg 以前我载入 ass 文件的时候 相对路径总出错 不知道是我用的不对 还是怎么样
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3232 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 12:46 PVG 20:46 LAX 04:46 JFK 07:46
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86