Reputation: 2077
This works fine in Ruby, and it should work:
puts 'don\'t'
But I want to run the same in BASH with Ruby:
%x(echo 'don\'t')
I get this error:
sh: -c: line 0: unexpected EOF while looking for matching
''`
Same error occurs with ``, system()
, Open3
My actual code snippet:
require 'open3'
module XdoTool
BIN = 'xdotool'
EXEC = ::ENV['PATH'].split(::File::PATH_SEPARATOR).map { |path| ::File.join(path, BIN) if ::File.executable?(::File.join(path, BIN)) }.compact.last
raise RuntimeError, "No #{BIN} found in the exported paths. Please make sure you have #{BIN} installed" unless EXEC
class << self
def type(str)
Open3.capture2("#{EXEC} type --delay 0 '#{str = str.gsub("'", '\'')}'")
str
end
end
end
# Types the quoted text anywhere.
XdoTool.type("What is the reason of the error?")
# sh: -c: line 0: unexpected EOF while looking for matching `''
# sh: -c: line 1: syntax error: unexpected end of file
XdoTool.type("What's the reason of the error?")
Please do note that the str can have anything. It can contain alphanumeric characters, symbols, emojis, or combination of all these things. How can I get around the problem with quotes here?
Upvotes: 0
Views: 301
Reputation: 532303
In shell, you simply cannot include a single quote inside a single-quoted string. It has to be in a double-quoted string. That means, if you want an argument that contains both, you need to concatenate separately quoted stings together.
echo 'He said "I can'"'"t'"'
or escape the double quotes inside a double-quoted string
echo "He said \"I can't\""
(Some shells provide yet another form of quoting that can contain an escaped single quote, namely $'He said "I can\'t"'
. However, that's an extension to the POSIX standard that you can't assume is supported by the
shell Ruby will use to execute your command.)
Upvotes: 2