踢足球的茄子 · 4-Python数据类型之元组-字符串 - ...· 1 年前 · |
善良的烤地瓜 · SegNet 语义分割网络以及其变体 ...· 1 年前 · |
知识渊博的斑马 · git log ...· 1 年前 · |
我在Linux上,正在编写一个子程序来更改mp3文件的ID标记。
此命令工作:
kid3-cli -c "tag 1" -c "set Title "TITLE"" -c "set Artist "ARTIST"" FILENAME.EXT
我尝试在ProcessBuilder中尝试这样的方法:
new ProcessBuilder(Arrays.asList("kid3-cli", "-c", "\"tag", "1\"", "-c", "\"set", "Title", "\"" + title + "\"\"",
"-c", "\"set", "Artist", "\"" + artist + "\"\"", path.toString()))
我还想把引号作为一个参数来处理:
new ProcessBuilder(Arrays.asList("kid3-cli", "-c", "\"tag 1\"", "-c", "\"set Title \"" + title + "\"\"",
"-c", "\"set Artist \"" + artist + "\"\"", path.toString())
它是否成功,可通过以下方式加以验证:
kid3-cli -c "get" SONG.EXT
当我运行该程序时(使用一些有用的调试语句,我得到:
INFO: COMMAND: kid3-cli -c "tag 1" -c "set Title "Unfinished Cathedral"" -c "set Artist "DAN TERMINUS"" /home/sarah/Music/Indexing/Temp/DAN TERMINUS - Unfinished Cathedral.mp3
标签的内容如下:
(base) sarah@MidnightStarSign:~/Music/Indexing/Temp$ kid3-cli -c "get" DAN\ TERMINUS\ -\ Unfinished\ Cathedral.mp3
File: MPEG 1 Layer 3 128 kbps 44100 Hz Joint Stereo 4:38
Name: DAN TERMINUS - Unfinished Cathedral.mp3
Tag 2: ID3v2.3.0
Title
Artist
Album
Comment Visit http://dan-terminus.bandcamp.com
Date 2014
Track Number 9
Album Artist DAN TERMINUS
Picture: Cover (front) cover
我相当肯定,我在给流程构建器的条目数量方面做错了什么,但我不确定。我怎么才能让它表现得正常呢?
编辑0:
奇怪的是。这也会失败(尽管它在查询命令时具有完全相同的输出,如果在bash上运行,则会更改标记):
new ProcessBuilder(Arrays.asList("bash", "-c", "\"kid3-cli -c \"tag 1\" -c \"set Title \"" + title + "\"\" -c \"set Artist \""
+ artist + "\"\"" + path.toString() + "\"");
虽然它会导致正确的字符串:
INFO: COMMAND: bash -c "kid3-cli -c "tag 1" -c "set Title "Unfinished Cathedral"" -c "set Artist "DAN TERMINUS""/home/sarah/Music/Indexing/Temp/DAN TERMINUS - Unfinished Cathedral.mp3"
发布于 2022-09-18 06:19:54
这里有两个问题:
bash
),而不是程序中的直接执行。
首先,让我们看一下命令的命令行版本:
此命令工作:
kid3-cli -c "tag 1" -c "set Title "TITLE"" -c "set Artist "ARTIST"" FILENAME.EXT
是的,它“有效”,但并不是因为你认为的原因。引号内的嵌套引号不只是神奇地起作用。对于任何解析器来说,几乎不可能知道哪些引号字符是参数的结尾,哪些字符是参数的一部分。
你真正要做的是:
kid3-cli -c "tag 1" -c "set Title "TITLE"" -c "set Artist "ARTIST"" FILENAME.EXT
╰──┬───╯ ╰┬╯ ╰─┬─╯ ╰┬╯ ╰──────┬── ────╯ ╰┬╯ ╰────────┬─ ─────╯ ╰────┬─────╯
arg0 arg1 arg2 arg3 arg4 arg5 arg6 arg7
(program
path)
正如您所看到的,每个引用的参数都是一个参数。这意味着您希望将每个引用的参数作为单个参数传递给ProcessBuilder,而不使用这些引号。双引号仅在shell (如
bash
)中是特殊的,它们指示带空格的值不应被shell拆分为多个参数。
但还有更多。当你这样做时:
"set Title "TITLE""
您没有在参数中指定带有双引号的参数。所有这些双引号字符都由shell解释,因此它们都不会传递给
kid3-cli
程序。
实际上正在发生的是将一个引用的字符串、一个未引用的标题、然后一个空的引号串连接到一个命令行参数中。这些都是完全相同的:
"set Title "TITLE""
"set Title "TITLE
'set Title 'TITLE
set\ Title\ TITLE
所以,那些双引号根本没有传递给程序。
ProcessBuilder不需要任何引号,因为它不是shell;而是直接执行带有给定参数的程序。您已经告诉ProcessBuilder什么构成了程序的单个参数,只需将每个这样的参数作为单独的字符串参数值传递即可。
(附带说明:
Arrays.asList
是不必要的。ProcessBuilder有
直接接受字符串参数的构造函数。
new ProcessBuilder("kid3-cli",
"-c", "tag 1",
"-c", "set Title \"" + title + "\"",