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

时间:2017-08-20 20:56:06

标签: java linux android-intentservice

我尝试创建一个拆分的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文件。

MainActivitiy.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);
                            }
                        }
            }
        }

    }

tarService.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命令文件名,但是使用拆分文件名是不同的。

1 个答案:

答案 0 :(得分:0)

exec()没有启动shell,所以它不理解重定向和管道等shell语法。如果使用shell语法,则必须通过sh -c ...启动shell。