View Javadoc
1   package org.codehaus.plexus.util.cli.shell;
2   
3   /*
4    * Copyright The Codehaus Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  import java.util.ArrayList;
20  import java.util.List;
21  
22  import org.codehaus.plexus.util.Os;
23  
24  /**
25   * @author Jason van Zyl
26   *
27   */
28  public class BourneShell extends Shell {
29  
30      public BourneShell() {
31          this(false);
32      }
33  
34      public BourneShell(boolean isLoginShell) {
35          setUnconditionalQuoting(true);
36          setShellCommand("/bin/sh");
37          setArgumentQuoteDelimiter('\'');
38          setExecutableQuoteDelimiter('\'');
39          setSingleQuotedArgumentEscaped(true);
40          setSingleQuotedExecutableEscaped(false);
41          setQuotedExecutableEnabled(true);
42          setArgumentEscapePattern("'\\%s'");
43  
44          if (isLoginShell) {
45              addShellArg("-l");
46          }
47      }
48  
49      /** {@inheritDoc} */
50      @Override
51      public String getExecutable() {
52          if (Os.isFamily(Os.FAMILY_WINDOWS)) {
53              return super.getExecutable();
54          }
55  
56          return quoteOneItem(super.getOriginalExecutable(), true);
57      }
58  
59      @Override
60      public List<String> getShellArgsList() {
61          List<String> shellArgs = new ArrayList<String>();
62          List<String> existingShellArgs = super.getShellArgsList();
63  
64          if ((existingShellArgs != null) && !existingShellArgs.isEmpty()) {
65              shellArgs.addAll(existingShellArgs);
66          }
67  
68          shellArgs.add("-c");
69  
70          return shellArgs;
71      }
72  
73      @Override
74      public String[] getShellArgs() {
75          String[] shellArgs = super.getShellArgs();
76          if (shellArgs == null) {
77              shellArgs = new String[0];
78          }
79  
80          if ((shellArgs.length > 0) && !shellArgs[shellArgs.length - 1].equals("-c")) {
81              String[] newArgs = new String[shellArgs.length + 1];
82  
83              System.arraycopy(shellArgs, 0, newArgs, 0, shellArgs.length);
84              newArgs[shellArgs.length] = "-c";
85  
86              shellArgs = newArgs;
87          }
88  
89          return shellArgs;
90      }
91  
92      @Override
93      protected String getExecutionPreamble() {
94          if (getWorkingDirectoryAsString() == null) {
95              return null;
96          }
97  
98          String dir = getWorkingDirectoryAsString();
99          StringBuilder sb = new StringBuilder();
100         sb.append("cd ");
101 
102         sb.append(quoteOneItem(dir, false));
103         sb.append(" && ");
104 
105         return sb.toString();
106     }
107 
108     /**
109      * <p>
110      * Unify quotes in a path for the Bourne Shell.
111      * </p>
112      *
113      * <pre>
114      * BourneShell.quoteOneItem(null)                       = null
115      * BourneShell.quoteOneItem("")                         = ''
116      * BourneShell.quoteOneItem("/test/quotedpath'abc")     = '/test/quotedpath'"'"'abc'
117      * BourneShell.quoteOneItem("/test/quoted path'abc")    = '/test/quoted pat'"'"'habc'
118      * BourneShell.quoteOneItem("/test/quotedpath\"abc")    = '/test/quotedpath"abc'
119      * BourneShell.quoteOneItem("/test/quoted path\"abc")   = '/test/quoted path"abc'
120      * BourneShell.quoteOneItem("/test/quotedpath\"'abc")   = '/test/quotedpath"'"'"'abc'
121      * BourneShell.quoteOneItem("/test/quoted path\"'abc")  = '/test/quoted path"'"'"'abc'
122      * </pre>
123      *
124      * @param path not null path.
125      * @return the path unified correctly for the Bourne shell.
126      */
127     @Override
128     protected String quoteOneItem(String path, boolean isExecutable) {
129         if (path == null) {
130             return null;
131         }
132 
133         StringBuilder sb = new StringBuilder();
134         sb.append("'");
135         sb.append(path.replace("'", "'\"'\"'"));
136         sb.append("'");
137 
138         return sb.toString();
139     }
140 }