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
精彩评论