HADOOP-6080. Introduce -skipTrash option to rm and rmr. Contributed by Jakob Homan.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@789875 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
e93ebeae51
commit
4824a54419
|
@ -154,6 +154,9 @@ Trunk (unreleased changes)
|
||||||
|
|
||||||
HADOOP-3315. Add a new, binary file foramt, TFile. (Hong Tang via cdouglas)
|
HADOOP-3315. Add a new, binary file foramt, TFile. (Hong Tang via cdouglas)
|
||||||
|
|
||||||
|
HADOOP-6080. Introduce -skipTrash option to rm and rmr.
|
||||||
|
(Jakob Homan via shv)
|
||||||
|
|
||||||
IMPROVEMENTS
|
IMPROVEMENTS
|
||||||
|
|
||||||
HADOOP-4565. Added CombineFileInputFormat to use data locality information
|
HADOOP-4565. Added CombineFileInputFormat to use data locality information
|
||||||
|
|
|
@ -325,10 +325,13 @@
|
||||||
<section>
|
<section>
|
||||||
<title> rm </title>
|
<title> rm </title>
|
||||||
<p>
|
<p>
|
||||||
<code>Usage: hadoop fs -rm URI [URI …] </code>
|
<code>Usage: hadoop fs -rm [-skipTrash] URI [URI …] </code>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Delete files specified as args. Only deletes non empty directory and files. Refer to rmr for recursive deletes.<br/>
|
Delete files specified as args. Only deletes non empty directory and files. If the <code>-skipTrash</code> option
|
||||||
|
is specified, the trash, if enabled, will be bypassed and the specified file(s) deleted immediately. This can be
|
||||||
|
useful when it is necessary to delete files from an over-quota directory.
|
||||||
|
Refer to rmr for recursive deletes.<br/>
|
||||||
Example:
|
Example:
|
||||||
</p>
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -344,9 +347,11 @@
|
||||||
<section>
|
<section>
|
||||||
<title> rmr </title>
|
<title> rmr </title>
|
||||||
<p>
|
<p>
|
||||||
<code>Usage: hadoop fs -rmr URI [URI …]</code>
|
<code>Usage: hadoop fs -rmr [-skipTrash] URI [URI …]</code>
|
||||||
</p>
|
</p>
|
||||||
<p>Recursive version of delete.<br/>
|
<p>Recursive version of delete. If the <code>-skipTrash</code> option
|
||||||
|
is specified, the trash, if enabled, will be bypassed and the specified file(s) deleted immediately. This can be
|
||||||
|
useful when it is necessary to delete files from an over-quota directory.<br/>
|
||||||
Example:
|
Example:
|
||||||
</p>
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
|
|
|
@ -1086,10 +1086,12 @@ public class FsShell extends Configured implements Tool {
|
||||||
* Delete all files that match the file pattern <i>srcf</i>.
|
* Delete all files that match the file pattern <i>srcf</i>.
|
||||||
* @param srcf a file pattern specifying source files
|
* @param srcf a file pattern specifying source files
|
||||||
* @param recursive if need to delete subdirs
|
* @param recursive if need to delete subdirs
|
||||||
|
* @param skipTrash Should we skip the trash, if it's enabled?
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* @see org.apache.hadoop.fs.FileSystem#globStatus(Path)
|
* @see org.apache.hadoop.fs.FileSystem#globStatus(Path)
|
||||||
*/
|
*/
|
||||||
void delete(String srcf, final boolean recursive) throws IOException {
|
void delete(String srcf, final boolean recursive, final boolean skipTrash)
|
||||||
|
throws IOException {
|
||||||
//rm behavior in Linux
|
//rm behavior in Linux
|
||||||
// [~/1207]$ ls ?.txt
|
// [~/1207]$ ls ?.txt
|
||||||
// x.txt z.txt
|
// x.txt z.txt
|
||||||
|
@ -1100,22 +1102,27 @@ public class FsShell extends Configured implements Tool {
|
||||||
new DelayedExceptionThrowing() {
|
new DelayedExceptionThrowing() {
|
||||||
@Override
|
@Override
|
||||||
void process(Path p, FileSystem srcFs) throws IOException {
|
void process(Path p, FileSystem srcFs) throws IOException {
|
||||||
delete(p, srcFs, recursive);
|
delete(p, srcFs, recursive, skipTrash);
|
||||||
}
|
}
|
||||||
}.globAndProcess(srcPattern, srcPattern.getFileSystem(getConf()));
|
}.globAndProcess(srcPattern, srcPattern.getFileSystem(getConf()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* delete a file */
|
/* delete a file */
|
||||||
private void delete(Path src, FileSystem srcFs, boolean recursive) throws IOException {
|
private void delete(Path src, FileSystem srcFs, boolean recursive,
|
||||||
|
boolean skipTrash) throws IOException {
|
||||||
if (srcFs.isDirectory(src) && !recursive) {
|
if (srcFs.isDirectory(src) && !recursive) {
|
||||||
throw new IOException("Cannot remove directory \"" + src +
|
throw new IOException("Cannot remove directory \"" + src +
|
||||||
"\", use -rmr instead");
|
"\", use -rmr instead");
|
||||||
}
|
}
|
||||||
Trash trashTmp = new Trash(srcFs, getConf());
|
|
||||||
if (trashTmp.moveToTrash(src)) {
|
if(!skipTrash) {
|
||||||
System.out.println("Moved to trash: " + src);
|
Trash trashTmp = new Trash(srcFs, getConf());
|
||||||
return;
|
if (trashTmp.moveToTrash(src)) {
|
||||||
|
System.out.println("Moved to trash: " + src);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (srcFs.delete(src, true)) {
|
if (srcFs.delete(src, true)) {
|
||||||
System.out.println("Deleted " + src);
|
System.out.println("Deleted " + src);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1312,8 +1319,8 @@ public class FsShell extends Configured implements Tool {
|
||||||
"The full syntax is: \n\n" +
|
"The full syntax is: \n\n" +
|
||||||
"hadoop fs [-fs <local | file system URI>] [-conf <configuration file>]\n\t" +
|
"hadoop fs [-fs <local | file system URI>] [-conf <configuration file>]\n\t" +
|
||||||
"[-D <property=value>] [-ls <path>] [-lsr <path>] [-df [<path>]] [-du <path>]\n\t" +
|
"[-D <property=value>] [-ls <path>] [-lsr <path>] [-df [<path>]] [-du <path>]\n\t" +
|
||||||
"[-dus <path>] [-mv <src> <dst>] [-cp <src> <dst>] [-rm <src>]\n\t" +
|
"[-dus <path>] [-mv <src> <dst>] [-cp <src> <dst>] [-rm [-skipTrash] <src>]\n\t" +
|
||||||
"[-rmr <src>] [-put <localsrc> ... <dst>] [-copyFromLocal <localsrc> ... <dst>]\n\t" +
|
"[-rmr [-skipTrash] <src>] [-put <localsrc> ... <dst>] [-copyFromLocal <localsrc> ... <dst>]\n\t" +
|
||||||
"[-moveFromLocal <localsrc> ... <dst>] [" +
|
"[-moveFromLocal <localsrc> ... <dst>] [" +
|
||||||
GET_SHORT_USAGE + "\n\t" +
|
GET_SHORT_USAGE + "\n\t" +
|
||||||
"[-getmerge <src> <localdst> [addnl]] [-cat <src>]\n\t" +
|
"[-getmerge <src> <localdst> [addnl]] [-cat <src>]\n\t" +
|
||||||
|
@ -1381,11 +1388,15 @@ public class FsShell extends Configured implements Tool {
|
||||||
"\t\tdestination. When copying multiple files, the destination\n" +
|
"\t\tdestination. When copying multiple files, the destination\n" +
|
||||||
"\t\tmust be a directory. \n";
|
"\t\tmust be a directory. \n";
|
||||||
|
|
||||||
String rm = "-rm <src>: \tDelete all files that match the specified file pattern.\n" +
|
String rm = "-rm [-skipTrash] <src>: \tDelete all files that match the specified file pattern.\n" +
|
||||||
"\t\tEquivlent to the Unix command \"rm <src>\"\n";
|
"\t\tEquivalent to the Unix command \"rm <src>\"\n" +
|
||||||
|
"\t\t-skipTrash option bypasses trash, if enabled, and immediately\n" +
|
||||||
|
"deletes <src>";
|
||||||
|
|
||||||
String rmr = "-rmr <src>: \tRemove all directories which match the specified file \n" +
|
String rmr = "-rmr [-skipTrash] <src>: \tRemove all directories which match the specified file \n" +
|
||||||
"\t\tpattern. Equivlent to the Unix command \"rm -rf <src>\"\n";
|
"\t\tpattern. Equivalent to the Unix command \"rm -rf <src>\"\n" +
|
||||||
|
"\t\t-skipTrash option bypasses trash, if enabled, and immediately\n" +
|
||||||
|
"deletes <src>";
|
||||||
|
|
||||||
String put = "-put <localsrc> ... <dst>: \tCopy files " +
|
String put = "-put <localsrc> ... <dst>: \tCopy files " +
|
||||||
"from the local file system \n\t\tinto fs. \n";
|
"from the local file system \n\t\tinto fs. \n";
|
||||||
|
@ -1573,8 +1584,6 @@ public class FsShell extends Configured implements Tool {
|
||||||
System.out.println(Count.DESCRIPTION);
|
System.out.println(Count.DESCRIPTION);
|
||||||
System.out.println(help);
|
System.out.println(help);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1584,6 +1593,15 @@ public class FsShell extends Configured implements Tool {
|
||||||
private int doall(String cmd, String argv[], int startindex) {
|
private int doall(String cmd, String argv[], int startindex) {
|
||||||
int exitCode = 0;
|
int exitCode = 0;
|
||||||
int i = startindex;
|
int i = startindex;
|
||||||
|
boolean rmSkipTrash = false;
|
||||||
|
|
||||||
|
// Check for -skipTrash option in rm/rmr
|
||||||
|
if(("-rm".equals(cmd) || "-rmr".equals(cmd))
|
||||||
|
&& "-skipTrash".equals(argv[i])) {
|
||||||
|
rmSkipTrash = true;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// for each source file, issue the command
|
// for each source file, issue the command
|
||||||
//
|
//
|
||||||
|
@ -1597,9 +1615,9 @@ public class FsShell extends Configured implements Tool {
|
||||||
} else if ("-mkdir".equals(cmd)) {
|
} else if ("-mkdir".equals(cmd)) {
|
||||||
mkdir(argv[i]);
|
mkdir(argv[i]);
|
||||||
} else if ("-rm".equals(cmd)) {
|
} else if ("-rm".equals(cmd)) {
|
||||||
delete(argv[i], false);
|
delete(argv[i], false, rmSkipTrash);
|
||||||
} else if ("-rmr".equals(cmd)) {
|
} else if ("-rmr".equals(cmd)) {
|
||||||
delete(argv[i], true);
|
delete(argv[i], true, rmSkipTrash);
|
||||||
} else if ("-df".equals(cmd)) {
|
} else if ("-df".equals(cmd)) {
|
||||||
df(argv[i]);
|
df(argv[i]);
|
||||||
} else if (Count.matches(cmd)) {
|
} else if (Count.matches(cmd)) {
|
||||||
|
@ -1708,8 +1726,8 @@ public class FsShell extends Configured implements Tool {
|
||||||
System.err.println(" [" + Count.USAGE + "]");
|
System.err.println(" [" + Count.USAGE + "]");
|
||||||
System.err.println(" [-mv <src> <dst>]");
|
System.err.println(" [-mv <src> <dst>]");
|
||||||
System.err.println(" [-cp <src> <dst>]");
|
System.err.println(" [-cp <src> <dst>]");
|
||||||
System.err.println(" [-rm <path>]");
|
System.err.println(" [-rm [-skipTrash] <path>]");
|
||||||
System.err.println(" [-rmr <path>]");
|
System.err.println(" [-rmr [-skipTrash] <path>]");
|
||||||
System.err.println(" [-expunge]");
|
System.err.println(" [-expunge]");
|
||||||
System.err.println(" [-put <localsrc> ... <dst>]");
|
System.err.println(" [-put <localsrc> ... <dst>]");
|
||||||
System.err.println(" [-copyFromLocal <localsrc> ... <dst>]");
|
System.err.println(" [-copyFromLocal <localsrc> ... <dst>]");
|
||||||
|
|
|
@ -140,7 +140,7 @@ public class TestTrash extends TestCase {
|
||||||
|
|
||||||
// Verify that we can recreate the file
|
// Verify that we can recreate the file
|
||||||
writeFile(fs, myFile);
|
writeFile(fs, myFile);
|
||||||
|
|
||||||
// Verify that we succeed in removing the whole directory
|
// Verify that we succeed in removing the whole directory
|
||||||
// along with the file inside it.
|
// along with the file inside it.
|
||||||
{
|
{
|
||||||
|
@ -256,6 +256,63 @@ public class TestTrash extends TestCase {
|
||||||
assertTrue(val == -1);
|
assertTrue(val == -1);
|
||||||
assertTrue(fs.exists(trashRoot));
|
assertTrue(fs.exists(trashRoot));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify skip trash option really works
|
||||||
|
|
||||||
|
// recreate directory and file
|
||||||
|
mkdir(fs, myPath);
|
||||||
|
writeFile(fs, myFile);
|
||||||
|
|
||||||
|
// Verify that skip trash option really skips the trash for files (rm)
|
||||||
|
{
|
||||||
|
String[] args = new String[3];
|
||||||
|
args[0] = "-rm";
|
||||||
|
args[1] = "-skipTrash";
|
||||||
|
args[2] = myFile.toString();
|
||||||
|
int val = -1;
|
||||||
|
try {
|
||||||
|
// Clear out trash
|
||||||
|
assertEquals(0, shell.run(new String [] { "-expunge" } ));
|
||||||
|
|
||||||
|
val = shell.run(args);
|
||||||
|
|
||||||
|
}catch (Exception e) {
|
||||||
|
System.err.println("Exception raised from Trash.run " +
|
||||||
|
e.getLocalizedMessage());
|
||||||
|
}
|
||||||
|
assertFalse(fs.exists(trashRoot)); // No new Current should be created
|
||||||
|
assertFalse(fs.exists(myFile));
|
||||||
|
assertTrue(val == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// recreate directory and file
|
||||||
|
mkdir(fs, myPath);
|
||||||
|
writeFile(fs, myFile);
|
||||||
|
|
||||||
|
// Verify that skip trash option really skips the trash for rmr
|
||||||
|
{
|
||||||
|
String[] args = new String[3];
|
||||||
|
args[0] = "-rmr";
|
||||||
|
args[1] = "-skipTrash";
|
||||||
|
args[2] = myPath.toString();
|
||||||
|
|
||||||
|
int val = -1;
|
||||||
|
try {
|
||||||
|
// Clear out trash
|
||||||
|
assertEquals(0, shell.run(new String [] { "-expunge" } ));
|
||||||
|
|
||||||
|
val = shell.run(args);
|
||||||
|
|
||||||
|
}catch (Exception e) {
|
||||||
|
System.err.println("Exception raised from Trash.run " +
|
||||||
|
e.getLocalizedMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
assertFalse(fs.exists(trashRoot)); // No new Current should be created
|
||||||
|
assertFalse(fs.exists(myPath));
|
||||||
|
assertFalse(fs.exists(myFile));
|
||||||
|
assertTrue(val == 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void trashNonDefaultFS(Configuration conf) throws IOException {
|
public static void trashNonDefaultFS(Configuration conf) throws IOException {
|
||||||
|
|
Loading…
Reference in New Issue