Runtime.getRuntime().exec 在命令中使用 PIPE



我正在尝试创建一个拆分的 TAR 文件并通过检查目录大小来读取进度。(我不能使用 PV 命令(。

有人可以解释为什么如果在 tarService 中.java我将命令更改为:

String cmd="su -c tar -cp -C /dev . | split -b 1G -a 3 - "+ fname;

在另一个进程完成之前,MainActivity 中的进程从不记录任何内容,而具有:

String cmd="su -c tar -cpf " + fname + " -C /dev .";

它有效!

在这两种情况下都要小心创建 tar 文件。

主要活动.java

public void startBackup(View v){
back= new BackgroundTask().execute();
}
private class BackgroundTask extends AsyncTask<Void, Integer, String> {

@Override
protected String doInBackground(Void... arg0) {
backup = new Intent(MainActivity.this, tarService.class);
backup.putExtra("fname", "test.tar);    
status=999;
startService(backup);
while (status == 999) {
try {
Process process = Runtime.getRuntime().exec("du -sk /dev");
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String line;
while ((line = bufferedReader.readLine()) != null) {
Log.d(TAG,line);
}
}
}
}
}

焦油服务.java

protected void onHandleIntent(Intent i) {
try{
location=i.getStringExtra("location");
fname=i.getStringExtra("fname");
// THIS WORKS
String cmd="su -c tar -cpf " + fname + " -C /dev .";
Process process = Runtime.getRuntime().exec(cmd);
int code=process.waitFor();
Intent intent = new Intent("BackupProcess");
intent.putExtra("status", code);
Log.d(TAG,Integer.toString(code));
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
} catch (IOException e) {
Log.e(TAG, e.getMessage());
throw new RuntimeException(e);
}
}

解决

有一个代码错误,我也将文件名传递给du命令,但拆分时文件名不同。

exec()不启动 shell,因此它不理解重定向和管道等 shell 语法。如果你使用 shell 语法,你必须通过sh -c ...启动一个 shell。

最新更新