lib/deployml/remote_shell.rb in deployml-0.4.0 vs lib/deployml/remote_shell.rb in deployml-0.4.1
- old
+ new
@@ -1,18 +1,16 @@
require 'deployml/shell'
require 'addressable/uri'
-require 'shellwords'
module DeploYML
#
# Represents a shell running on a remote server.
#
class RemoteShell
include Shell
- include Shellwords
# The URI of the remote shell
attr_reader :uri
# The history of the Remote Shell
@@ -94,11 +92,11 @@
# @return [String]
# A single command string.
#
def join
@history.map { |command|
- command.map { |word| shellescape(word) }.join(' ')
+ command.map { |word| shellescape(word.to_s) }.join(' ')
}.join(' && ')
end
#
# Converts the URI to one compatible with SSH.
@@ -125,20 +123,62 @@
# Add the -p option if an alternate destination port is given
if @uri.port
options += ['-p', @uri.port.to_s]
end
+ # append the SSH URI
options << ssh_uri
- options += args
+ # append the additional arguments
+ args.each { |arg| options << arg.to_s }
+
return system('ssh',*options)
end
#
# Replays the command history on the remote server.
#
def replay
ssh(self.join) unless @history.empty?
+ end
+
+ protected
+
+ #
+ # Escapes a string so that it can be safely used in a Bourne shell
+ # command line.
+ #
+ # Note that a resulted string should be used unquoted and is not
+ # intended for use in double quotes nor in single quotes.
+ #
+ # @param [String] str
+ # The string to escape.
+ #
+ # @return [String]
+ # The shell-escaped string.
+ #
+ # @example
+ # open("| grep #{Shellwords.escape(pattern)} file") { |pipe|
+ # # ...
+ # }
+ #
+ # @note Vendored from `shellwords.rb` line 72 from Ruby 1.9.2.
+ #
+ def shellescape(str)
+ # An empty argument will be skipped, so return empty quotes.
+ return "''" if str.empty?
+
+ str = str.dup
+
+ # Process as a single byte sequence because not all shell
+ # implementations are multibyte aware.
+ str.gsub!(/([^A-Za-z0-9_\-.,:\/@\n])/n, "\\\\\\1")
+
+ # A LF cannot be escaped with a backslash because a backslash + LF
+ # combo is regarded as line continuation and simply ignored.
+ str.gsub!(/\n/, "'\n'")
+
+ return str
end
end
end