我有一段可以运行的 Java 代码:
public class GetNumberOfFiles {
protected long GetNumberOfFilesMethod(String folder){
try {
Process p = Runtime.getRuntime().exec(new String[]{"bash", "-c", "cd " + folder + "&& find . -type f | grep :*.txt "});
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
return stdInput.lines().count();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
我也创建了具有类似逻辑的代码,但经过几次尝试后,我将 bash 代码放入了单独的文件中。
Java 代码:
protected String CheckUserMethod(String user){
try {
Process p = Runtime.getRuntime().exec(new String[]{"bash", "-c", "~/Final-Year/src/query", "&& ./checkuser.sh", user});
BufferedReader srdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
String a = null;
while ((a = srdInput.readLine()) != null)
{
System.out.println(a);
}
return a;
}catch (Exception e){
throw new RuntimeException(e);
}
}
bash 代码是:
#!/bin/bash
# shellcheck disable=SC2237
if ! [ -z "$1" ]
then
echo "$1"
cd ~/Final-Year/maps/ && find "$1" -maxdepth 0 -type d -printf 1
fi
当我从终端执行时,代码运行完美,如本例所示:
问题是,当我执行 Java 代码时甚至没有执行 bash 文件。你有什么建议吗?
答案1
当您使用时bash -c
,后的第一个参数将-c
被视为命令,并且任何其他参数都将作为位置参数传递。
在你的第一个片段中,
{"bash", "-c", "cd " + folder + "&& find . -type f | grep :*.txt "}
你传递的是一个连接的字符串参数"cd " + folder + "&& find . -type f | grep :*.txt "
,而在第二个片段中,
{"bash", "-c", "~/Final-Year/src/query", "&& ./checkuser.sh", user}
你传递了 3 个参数:
~/Final-Year/src/query
(可能应该是cd ~/Final-Year/src/query
&& ./checkuser.sh
user
所以它相当于
bash -c '~/Final-Year/src/query' '&& ./checkuser.sh' user
执行bash -c '~/Final-Year/src/query'
或(更正)bash -c 'cd ~/Final-Year/src/query'
以文字字符串&& ./checkuser.sh
作为位置参数$0
,以替换的 Java 变量user
作为位置参数$1
你可能想要的是
bash -c 'cd ~/Final-Year/src/query && ./checkuser.sh user'
而是
{"bash", "-c", "cd ~/Final-Year/src/query && ./checkuser.sh " + user}
或者,你可以使用位置参数数组,例如
{"bash", "-c", "cd ~/Final-Year/src/query && ./checkuser.sh \"$1\"", "bash", user}
其中 shell 的名称bash
作为 传递$0
(您可以在此处使用任意字符串),而 Java 变量user
作为 传递$1
。