开发者

Ruby: execute shell command 'echo' with '-n' option

I'd like to run the following shell command from Ruby, which copies a string into the clipboard (on OS X), 'n' is suppressing the line break after the string caused by echo:

echo -n foobar | pbcopy

—> works, fine, now the clipboard contains "foobar"

I've tried the following, but all of them always copy the option '-n' as well into the clipboard:

%x[echo -n 'foobar' | pbcopy]
%x[echo -n foobar | pbcopy]
system "echo -n 'foobar' | pbcopy"开发者_运维百科
system "echo -n foobar | pbcopy"
exec 'echo -n "foobar" | pbcopy'
`echo -n "foobar" | pbcopy`
IO.popen "echo -n 'foobar' | pbcopy"

What is the proper way to achieve this?


Your problem is that -n is only understood by the bash built-in echo command; when you say %x[...] (or any of your other variations on it), the command is fed to /bin/sh which will act like a POSIX shell even if it really is /bin/bash. The solution is to explicitly feed your shell commands to bash:

%x[/bin/bash -c 'echo -n foobar' | pbcopy]

You will, of course, need to be careful with your quoting on whatever foobar really is. The -c switch essentially tells /bin/bash that you're giving it an inlined script:

-c string
If the -c option is present, then commands are read from string. If there are arguments after the string, they are assigned to the positional parameters, starting with $0.


Because echo behaves differently in different shells and in /bin/echo, it's recommended that you use printf instead.

No newline:

%x[printf '%s' 'foobar' | pbcopy]

With a newline:

%x[printf '%s\n' 'foobar' | pbcopy]


You might be reinventing a wheel.

IRB_Tools and Utility_Belt, which are both used to tweak IRB, provide an ability to use the clipboard. Both are collections of existing gems, so I did a quick search using gem clipboard -r and came up with:

clipboard (0.9.7)
win32-clipboard (0.5.2)

Looking at RubyDoc.info for clipboard reveals:

clipboard

Access the clipboard and do not care if the OS is Linux, MacOS or Windows.

Usage

You have Clipboard.copy,

Clipboard.paste and

Clipboard.clear

Have fun ;)


EDIT: If you check the source on the linked page, for the Mac you'll see for copy:

def copy(data)
  Open3.popen3( 'pbcopy' ){ |input,_,_| input << data }
  paste
end

and for paste you'll see:

def paste(_ = nil)
  `pbpaste`
end

and clear is simply:

def clear
  copy ''
end

Those should get you pointed in the right direction.


This might look like an ugly workaround, but I'm pretty sure it'll work:

Create an executable file called myfoobar.sh containing the line you want to execute.

#! /bin/sh
echo -n foobar | pbcopy

Then invoke that file from ruby.


Use the sutil for correct setup:


    $ ssh-copy-id user@host

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜