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   * @version $Id$
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      public String getExecutable()
56      {
57          if ( Os.isFamily( Os.FAMILY_WINDOWS ) )
58          {
59              return super.getExecutable();
60          }
61  
62          return quoteOneItem( super.getOriginalExecutable(), true );
63      }
64  
65      public List<String> getShellArgsList()
66      {
67          List<String> shellArgs = new ArrayList<String>();
68          List<String> existingShellArgs = super.getShellArgsList();
69  
70          if ( ( existingShellArgs != null ) && !existingShellArgs.isEmpty() )
71          {
72              shellArgs.addAll( existingShellArgs );
73          }
74  
75          shellArgs.add( "-c" );
76  
77          return shellArgs;
78      }
79  
80      public String[] getShellArgs()
81      {
82          String[] shellArgs = super.getShellArgs();
83          if ( shellArgs == null )
84          {
85              shellArgs = new String[0];
86          }
87  
88          if ( ( shellArgs.length > 0 ) && !shellArgs[shellArgs.length - 1].equals( "-c" ) )
89          {
90              String[] newArgs = new String[shellArgs.length + 1];
91  
92              System.arraycopy( shellArgs, 0, newArgs, 0, shellArgs.length );
93              newArgs[shellArgs.length] = "-c";
94  
95              shellArgs = newArgs;
96          }
97  
98          return shellArgs;
99      }
100 
101     protected String getExecutionPreamble()
102     {
103         if ( getWorkingDirectoryAsString() == null )
104         {
105             return null;
106         }
107 
108         String dir = getWorkingDirectoryAsString();
109         StringBuilder sb = new StringBuilder();
110         sb.append( "cd " );
111 
112         sb.append( quoteOneItem( dir, false ) );
113         sb.append( " && " );
114 
115         return sb.toString();
116     }
117 
118     /**
119      * <p>
120      * Unify quotes in a path for the Bourne Shell.
121      * </p>
122      *
123      * <pre>
124      * BourneShell.quoteOneItem(null)                       = null
125      * BourneShell.quoteOneItem("")                         = ''
126      * BourneShell.quoteOneItem("/test/quotedpath'abc")     = '/test/quotedpath'"'"'abc'
127      * BourneShell.quoteOneItem("/test/quoted path'abc")    = '/test/quoted pat'"'"'habc'
128      * BourneShell.quoteOneItem("/test/quotedpath\"abc")    = '/test/quotedpath"abc'
129      * BourneShell.quoteOneItem("/test/quoted path\"abc")   = '/test/quoted path"abc'
130      * BourneShell.quoteOneItem("/test/quotedpath\"'abc")   = '/test/quotedpath"'"'"'abc'
131      * BourneShell.quoteOneItem("/test/quoted path\"'abc")  = '/test/quoted path"'"'"'abc'
132      * </pre>
133      *
134      * @param path not null path.
135      * @return the path unified correctly for the Bourne shell.
136      */
137     protected String quoteOneItem( String path, boolean isExecutable )
138     {
139         if ( path == null )
140         {
141             return null;
142         }
143 
144         StringBuilder sb = new StringBuilder();
145         sb.append( "'" );
146         sb.append( path.replace( "'", "'\"'\"'" ) );
147         sb.append( "'" );
148 
149         return sb.toString();
150     }
151 }