15 Volts
15 Volts

Reputation: 2077

While using a single quote in a string in shell with Ruby I get sh: -c: line 0: unexpected EOF while looking for matching `''

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

Answers (1)

chepner
chepner

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

Related Questions