HADOOP-13434. Add bash quoting to Shell class. (Owen O'Malley)

This commit is contained in:
Arpit Agarwal 2016-08-03 14:28:44 -07:00
parent 2bf4e76370
commit 9669779f2c
2 changed files with 45 additions and 12 deletions

View File

@ -83,8 +83,23 @@ abstract public class Shell {
} }
} }
/** a Unix command to get the current user's name */ /**
public final static String USER_NAME_COMMAND = "whoami"; * Quote the given arg so that bash will interpret it as a single value.
* Note that this quotes it for one level of bash, if you are passing it
* into a badly written shell script, you need to fix your shell script.
* @param arg the argument to quote
* @return the quoted string
*/
static String bashQuote(String arg) {
StringBuilder buffer = new StringBuilder(arg.length() + 2);
buffer.append('\'');
buffer.append(arg.replace("'", "'\\''"));
buffer.append('\'');
return buffer.toString();
}
/** a Unix command to get the current user's name: {@value}. */
public static final String USER_NAME_COMMAND = "whoami";
/** Windows CreateProcess synchronization object */ /** Windows CreateProcess synchronization object */
public static final Object WindowsProcessLaunchLock = new Object(); public static final Object WindowsProcessLaunchLock = new Object();
@ -134,7 +149,7 @@ abstract public class Shell {
/** a Unix command to get the current user's groups list */ /** a Unix command to get the current user's groups list */
public static String[] getGroupsCommand() { public static String[] getGroupsCommand() {
return (WINDOWS)? new String[]{"cmd", "/c", "groups"} return (WINDOWS)? new String[]{"cmd", "/c", "groups"}
: new String[]{"bash", "-c", "groups"}; : new String[]{"groups"};
} }
/** /**
@ -144,17 +159,21 @@ abstract public class Shell {
* i.e. the user's primary group will be included twice. * i.e. the user's primary group will be included twice.
*/ */
public static String[] getGroupsForUserCommand(final String user) { public static String[] getGroupsForUserCommand(final String user) {
//'groups username' command return is non-consistent across different unixes //'groups username' command return is inconsistent across different unixes
return (WINDOWS)? new String[] { WINUTILS, "groups", "-F", "\"" + user + "\""} if (WINDOWS) {
: new String [] {"bash", "-c", "id -gn " + user return new String[]
+ "&& id -Gn " + user}; {getWinUtilsPath(), "groups", "-F", "\"" + user + "\""};
} else {
String quotedUser = bashQuote(user);
return new String[] {"bash", "-c", "id -gn " + quotedUser +
"; id -Gn " + quotedUser};
}
} }
/** a Unix command to get a given netgroup's user list */ /** a Unix command to get a given netgroup's user list */
public static String[] getUsersForNetgroupCommand(final String netgroup) { public static String[] getUsersForNetgroupCommand(final String netgroup) {
//'groups username' command return is non-consistent across different unixes //'groups username' command return is non-consistent across different unixes
return (WINDOWS)? new String [] {"cmd", "/c", "getent netgroup " + netgroup} return new String[] {"getent", "netgroup", netgroup};
: new String [] {"bash", "-c", "getent netgroup " + netgroup};
} }
/** Return a command to get permission information. */ /** Return a command to get permission information. */
@ -260,8 +279,9 @@ abstract public class Shell {
*/ */
public static String[] getRunScriptCommand(File script) { public static String[] getRunScriptCommand(File script) {
String absolutePath = script.getAbsolutePath(); String absolutePath = script.getAbsolutePath();
return WINDOWS ? new String[] { "cmd", "/c", absolutePath } : return WINDOWS ?
new String[] { "/bin/bash", absolutePath }; new String[] {"cmd", "/c", absolutePath }
: new String[] {"/bin/bash", bashQuote(absolutePath) };
} }
/** a Unix command to set permission */ /** a Unix command to set permission */
@ -744,6 +764,12 @@ abstract public class Shell {
/** Execute the shell command. */ /** Execute the shell command. */
public void execute() throws IOException { public void execute() throws IOException {
for (String s : command) {
if (s == null) {
throw new IOException("(null) entry in command string: "
+ StringUtils.join(" ", command));
}
}
this.run(); this.run();
} }

View File

@ -209,4 +209,11 @@ public class TestShell extends TestCase {
assertEquals(2, command.getRunCount()); assertEquals(2, command.getRunCount());
} }
} }
@Test
public void testBashQuote() {
assertEquals("'foobar'", Shell.bashQuote("foobar"));
assertEquals("'foo'\\''bar'", Shell.bashQuote("foo'bar"));
assertEquals("''\\''foo'\\''bar'\\'''", Shell.bashQuote("'foo'bar'"));
}
} }