HADOOP-13522. Add %A and %a formats for fs -stat command to print permissions. Contributed by Alex Garbarini.
(cherry picked from commit bedfec0c10
)
This commit is contained in:
parent
278eeb1056
commit
b2618685fb
|
@ -169,6 +169,18 @@ public class FsPermission implements Writable {
|
|||
return toShort();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the FsPermission in an octal format.
|
||||
*
|
||||
* @return short Unlike {@link #toShort()} which provides a binary
|
||||
* representation, this method returns the standard octal style permission.
|
||||
*/
|
||||
public short toOctal() {
|
||||
int n = this.toShort();
|
||||
int octal = (n>>>9&1)*1000 + (n>>>6&7)*100 + (n>>>3&7)*10 + (n&7);
|
||||
return (short)octal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof FsPermission) {
|
||||
|
|
|
@ -31,6 +31,8 @@ import org.apache.hadoop.fs.FileStatus;
|
|||
/**
|
||||
* Print statistics about path in specified format.
|
||||
* Format sequences:<br>
|
||||
* %a: Permissions in octal<br>
|
||||
* %A: Permissions in symbolic style<br>
|
||||
* %b: Size of file in blocks<br>
|
||||
* %F: Type<br>
|
||||
* %g: Group name of owner<br>
|
||||
|
@ -56,7 +58,8 @@ class Stat extends FsCommand {
|
|||
public static final String USAGE = "[format] <path> ...";
|
||||
public static final String DESCRIPTION =
|
||||
"Print statistics about the file/directory at <path>" + NEWLINE +
|
||||
"in the specified format. Format accepts filesize in" + NEWLINE +
|
||||
"in the specified format. Format accepts permissions in" + NEWLINE +
|
||||
"octal (%a) and symbolic (%A), filesize in" + NEWLINE +
|
||||
"blocks (%b), type (%F), group name of owner (%g)," + NEWLINE +
|
||||
"name (%n), block size (%o), replication (%r), user name" + NEWLINE +
|
||||
"of owner (%u), modification date (%y, %Y)." + NEWLINE +
|
||||
|
@ -95,6 +98,12 @@ class Stat extends FsCommand {
|
|||
// this silently drops a trailing %?
|
||||
if (i + 1 == fmt.length) break;
|
||||
switch (fmt[++i]) {
|
||||
case 'a':
|
||||
buf.append(stat.getPermission().toOctal());
|
||||
break;
|
||||
case 'A':
|
||||
buf.append(stat.getPermission());
|
||||
break;
|
||||
case 'b':
|
||||
buf.append(stat.getLen());
|
||||
break;
|
||||
|
|
|
@ -639,11 +639,11 @@ stat
|
|||
|
||||
Usage: `hadoop fs -stat [format] <path> ...`
|
||||
|
||||
Print statistics about the file/directory at \<path\> in the specified format. Format accepts filesize in blocks (%b), type (%F), group name of owner (%g), name (%n), block size (%o), replication (%r), user name of owner(%u), and modification date (%y, %Y). %y shows UTC date as "yyyy-MM-dd HH:mm:ss" and %Y shows milliseconds since January 1, 1970 UTC. If the format is not specified, %y is used by default.
|
||||
Print statistics about the file/directory at \<path\> in the specified format. Format accepts permissions in octal (%a) and symbolic (%A), filesize in blocks (%b), type (%F), group name of owner (%g), name (%n), block size (%o), replication (%r), user name of owner(%u), and modification date (%y, %Y). %y shows UTC date as "yyyy-MM-dd HH:mm:ss" and %Y shows milliseconds since January 1, 1970 UTC. If the format is not specified, %y is used by default.
|
||||
|
||||
Example:
|
||||
|
||||
* `hadoop fs -stat "%F %u:%g %b %y %n" /file`
|
||||
* `hadoop fs -stat "%F %a %u:%g %b %y %n" /file`
|
||||
|
||||
Exit Code: Returns 0 on success and -1 on error.
|
||||
|
||||
|
|
|
@ -859,7 +859,11 @@
|
|||
</comparator>
|
||||
<comparator>
|
||||
<type>RegexpComparator</type>
|
||||
<expected-output>^( |\t)*in the specified format. Format accepts filesize in( )*</expected-output>
|
||||
<expected-output>^( |\t)*in the specified format. Format accepts permissions in( )*</expected-output>
|
||||
</comparator>
|
||||
<comparator>
|
||||
<type>RegexpComparator</type>
|
||||
<expected-output>^( |\t)*octal \(%a\) and symbolic \(%A\), filesize in( )*</expected-output>
|
||||
</comparator>
|
||||
<comparator>
|
||||
<type>RegexpComparator</type>
|
||||
|
|
|
@ -1954,17 +1954,31 @@ public class TestDFSShell {
|
|||
out.toString(), String.format("%s%n%s%n", mtime1, mtime2));
|
||||
|
||||
doFsStat(dfs.getConf(), "%F %u:%g %b %y %n");
|
||||
|
||||
out.reset();
|
||||
doFsStat(dfs.getConf(), "%F %u:%g %b %y %n", testDir1);
|
||||
|
||||
doFsStat(dfs.getConf(), "%F %a %A %u:%g %b %y %n", testDir1);
|
||||
assertTrue(out.toString(), out.toString().contains(mtime1));
|
||||
assertTrue(out.toString(), out.toString().contains("directory"));
|
||||
assertTrue(out.toString(), out.toString().contains(status1.getGroup()));
|
||||
assertTrue(out.toString(),
|
||||
out.toString().contains(status1.getPermission().toString()));
|
||||
|
||||
int n = status1.getPermission().toShort();
|
||||
int octal = (n>>>9&1)*1000 + (n>>>6&7)*100 + (n>>>3&7)*10 + (n&7);
|
||||
assertTrue(out.toString(),
|
||||
out.toString().contains(String.valueOf(octal)));
|
||||
|
||||
out.reset();
|
||||
doFsStat(dfs.getConf(), "%F %u:%g %b %y %n", testDir1, testFile2);
|
||||
doFsStat(dfs.getConf(), "%F %a %A %u:%g %b %y %n", testDir1, testFile2);
|
||||
|
||||
n = status2.getPermission().toShort();
|
||||
octal = (n>>>9&1)*1000 + (n>>>6&7)*100 + (n>>>3&7)*10 + (n&7);
|
||||
assertTrue(out.toString(), out.toString().contains(mtime1));
|
||||
assertTrue(out.toString(), out.toString().contains("regular file"));
|
||||
assertTrue(out.toString(),
|
||||
out.toString().contains(status2.getPermission().toString()));
|
||||
assertTrue(out.toString(),
|
||||
out.toString().contains(String.valueOf(octal)));
|
||||
assertTrue(out.toString(), out.toString().contains(mtime2));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue