Search code examples
javaandroidshellrmdir

Android can't exec rm -r


I have an application that has a directory on the SD card. The application saves notes in a new subdirectory. I want to delete the whole subdirectory using shell command "rm -r" but the application throws an exception:

04-02 23:14:23.410: W/System.err(14891): java.io.IOException: Error running exec(). Command: [cd, /mnt/sdcard/mynote, &&, rm, -r, aaa] Working Directory: null Environment: null

Can anyone help me?


Solution

  • This happens because you used Runtime.exec(String). Never use this function. It's hard to predict and only works in trivial cases. Always use Runtime.exec(String[]).

    Since cd and && are not commands but shell features, you need to manually invoke a shell for them to work:

    Runtime.getRuntime().exec(new String[] {
        "sh", "-c", "cd /mnt/sdcard/mynote && rm -r aaa"  
    });
    

    On a related note, you should never pass String data unescaped to shells. For example, this is wrong:

    // Insecure, buggy and wrong!
    String target = "aaa";
    Runtime.getRuntime().exec(new String[] {
        "sh", "-c", "cd /mnt/sdcard/mynote && rm -r " + target  
    });
    

    The correct way is to pass data as separate parameters to the shell, and reference them from your command:

    // Secure and correct
    String target = "aaa";
    Runtime.getRuntime().exec(new String[] {
        "sh", "-c", "cd /mnt/sdcard/mynote && rm -r \"$1\"", "--", target
    });
    

    For example, if a file is named * or My file, the incorrect version will delete a whole bunch of completely unrelated files. The correct version does not.