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 org.codehaus.plexus.util.Os;
20  
21  import java.util.ArrayList;
22  import java.util.List;
23  
24  /**
25   * @author Jason van Zyl
26   *
27   */
28  public class BourneShell
29      extends Shell
30  {
31  
32      public BourneShell()
33      {
34          this( false );
35      }
36  
37      public BourneShell( boolean isLoginShell )
38      {
39          setUnconditionalQuoting( true );
40          setShellCommand( "/bin/sh" );
41          setArgumentQuoteDelimiter( '\'' );
42          setExecutableQuoteDelimiter( '\'' );
43          setSingleQuotedArgumentEscaped( true );
44          setSingleQuotedExecutableEscaped( false );
45          setQuotedExecutableEnabled( true );
46          setArgumentEscapePattern( "'\\%s'" );
47  
48          if ( isLoginShell )
49          {
50              addShellArg( "-l" );
51          }
52      }
53  
54      /** {@inheritDoc} */
55      @Override
56      public String getExecutable()
57      {
58          if ( Os.isFamily( Os.FAMILY_WINDOWS ) )
59          {
60              return super.getExecutable();
61          }
62  
63          return quoteOneItem( super.getOriginalExecutable(), true );
64      }
65  
66      @Override
67      public List<String> getShellArgsList()
68      {
69          List<String> shellArgs = new ArrayList<String>();
70          List<String> existingShellArgs = super.getShellArgsList();
71  
72          if ( ( existingShellArgs != null ) && !existingShellArgs.isEmpty() )
73          {
74              shellArgs.addAll( existingShellArgs );
75          }
76  
77          shellArgs.add( "-c" );
78  
79          return shellArgs;
80      }
81  
82      @Override
83      public String[] getShellArgs()
84      {
85          String[] shellArgs = super.getShellArgs();
86          if ( shellArgs == null )
87          {
88              shellArgs = new String[0];
89          }
90  
91          if ( ( shellArgs.length > 0 ) && !shellArgs[shellArgs.length - 1].equals( "-c" ) )
92          {
93              String[] newArgs = new String[shellArgs.length + 1];
94  
95              System.arraycopy( shellArgs, 0, newArgs, 0, shellArgs.length );
96              newArgs[shellArgs.length] = "-c";
97  
98              shellArgs = newArgs;
99          }
100 
101         return shellArgs;
102     }
103 
104     @Override
105     protected String getExecutionPreamble()
106     {
107         if ( getWorkingDirectoryAsString() == null )
108         {
109             return null;
110         }
111 
112         String dir = getWorkingDirectoryAsString();
113         StringBuilder sb = new StringBuilder();
114         sb.append( "cd " );
115 
116         sb.append( quoteOneItem( dir, false ) );
117         sb.append( " && " );
118 
119         return sb.toString();
120     }
121 
122     /**
123      * <p>
124      * Unify quotes in a path for the Bourne Shell.
125      * </p>
126      *
127      * <pre>
128      * BourneShell.quoteOneItem(null)                       = null
129      * BourneShell.quoteOneItem("")                         = ''
130      * BourneShell.quoteOneItem("/test/quotedpath'abc")     = '/test/quotedpath'"'"'abc'
131      * BourneShell.quoteOneItem("/test/quoted path'abc")    = '/test/quoted pat'"'"'habc'
132      * BourneShell.quoteOneItem("/test/quotedpath\"abc")    = '/test/quotedpath"abc'
133      * BourneShell.quoteOneItem("/test/quoted path\"abc")   = '/test/quoted path"abc'
134      * BourneShell.quoteOneItem("/test/quotedpath\"'abc")   = '/test/quotedpath"'"'"'abc'
135      * BourneShell.quoteOneItem("/test/quoted path\"'abc")  = '/test/quoted path"'"'"'abc'
136      * </pre>
137      *
138      * @param path not null path.
139      * @return the path unified correctly for the Bourne shell.
140      */
141     @Override
142     protected String quoteOneItem( String path, boolean isExecutable )
143     {
144         if ( path == null )
145         {
146             return null;
147         }
148 
149         StringBuilder sb = new StringBuilder();
150         sb.append( "'" );
151         sb.append( path.replace( "'", "'\"'\"'" ) );
152         sb.append( "'" );
153 
154         return sb.toString();
155     }
156 }