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();
|
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
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (obj instanceof FsPermission) {
|
if (obj instanceof FsPermission) {
|
||||||
|
|
|
@ -31,6 +31,8 @@ import org.apache.hadoop.fs.FileStatus;
|
||||||
/**
|
/**
|
||||||
* Print statistics about path in specified format.
|
* Print statistics about path in specified format.
|
||||||
* Format sequences:<br>
|
* Format sequences:<br>
|
||||||
|
* %a: Permissions in octal<br>
|
||||||
|
* %A: Permissions in symbolic style<br>
|
||||||
* %b: Size of file in blocks<br>
|
* %b: Size of file in blocks<br>
|
||||||
* %F: Type<br>
|
* %F: Type<br>
|
||||||
* %g: Group name of owner<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 USAGE = "[format] <path> ...";
|
||||||
public static final String DESCRIPTION =
|
public static final String DESCRIPTION =
|
||||||
"Print statistics about the file/directory at <path>" + NEWLINE +
|
"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 +
|
"blocks (%b), type (%F), group name of owner (%g)," + NEWLINE +
|
||||||
"name (%n), block size (%o), replication (%r), user name" + NEWLINE +
|
"name (%n), block size (%o), replication (%r), user name" + NEWLINE +
|
||||||
"of owner (%u), modification date (%y, %Y)." + NEWLINE +
|
"of owner (%u), modification date (%y, %Y)." + NEWLINE +
|
||||||
|
@ -95,6 +98,12 @@ class Stat extends FsCommand {
|
||||||
// this silently drops a trailing %?
|
// this silently drops a trailing %?
|
||||||
if (i + 1 == fmt.length) break;
|
if (i + 1 == fmt.length) break;
|
||||||
switch (fmt[++i]) {
|
switch (fmt[++i]) {
|
||||||
|
case 'a':
|
||||||
|
buf.append(stat.getPermission().toOctal());
|
||||||
|
break;
|
||||||
|
case 'A':
|
||||||
|
buf.append(stat.getPermission());
|
||||||
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
buf.append(stat.getLen());
|
buf.append(stat.getLen());
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -639,11 +639,11 @@ stat
|
||||||
|
|
||||||
Usage: `hadoop fs -stat [format] <path> ...`
|
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:
|
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.
|
Exit Code: Returns 0 on success and -1 on error.
|
||||||
|
|
||||||
|
|
|
@ -859,7 +859,11 @@
|
||||||
</comparator>
|
</comparator>
|
||||||
<comparator>
|
<comparator>
|
||||||
<type>RegexpComparator</type>
|
<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>
|
||||||
<comparator>
|
<comparator>
|
||||||
<type>RegexpComparator</type>
|
<type>RegexpComparator</type>
|
||||||
|
|
|
@ -1954,17 +1954,31 @@ public class TestDFSShell {
|
||||||
out.toString(), String.format("%s%n%s%n", mtime1, mtime2));
|
out.toString(), String.format("%s%n%s%n", mtime1, mtime2));
|
||||||
|
|
||||||
doFsStat(dfs.getConf(), "%F %u:%g %b %y %n");
|
doFsStat(dfs.getConf(), "%F %u:%g %b %y %n");
|
||||||
|
|
||||||
out.reset();
|
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(mtime1));
|
||||||
assertTrue(out.toString(), out.toString().contains("directory"));
|
assertTrue(out.toString(), out.toString().contains("directory"));
|
||||||
assertTrue(out.toString(), out.toString().contains(status1.getGroup()));
|
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();
|
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(mtime1));
|
||||||
assertTrue(out.toString(), out.toString().contains("regular file"));
|
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));
|
assertTrue(out.toString(), out.toString().contains(mtime2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue