Ruby: execute an echo shell command with the -n option

I would like to run the following shell command from Ruby, which copies the line to the clipboard (on OS X), 'n' suppresses line break after line called by echo :

 echo -n foobar | pbcopy 

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

I tried the following, but they all always copy the -n option also to 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 right way to achieve this?

+6
ruby shell macos
source share
5 answers

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

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

Of course, you should be careful with your quoting on any foobar actually. The -c switch essentially tells /bin/bash that you are giving it a built-in script:

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

+7
source share

Since echo behaves differently in different shells and in /bin/echo , we recommend using printf instead.

No new line:

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

With a new line:

 %x[printf '%s\n' 'foobar' | pbcopy] 
+6
source share

You may have invented the wheel.

IRB_Tools and Utility_Belt, which are used to configure IRB, provide the 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) 

A look at the RubyDoc.info for the clipboard shows:

Clipboard

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

Using

You have Clipboard.copy,

Clipboard.paste and

Clipboard.clear

Good luck;)


EDIT: if you check the source on the linked page, for Mac you will see for copy:

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

and for pasta you will see:

 def paste(_ = nil) `pbpaste` end 

and clear is simple:

 def clear copy '' end 

Those who should make you point in the right direction.

+2
source share

This may look like an ugly workaround, but I'm sure it will work:

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

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

Then call this file from ruby.

+1
source share

Use sutil to configure correctly:

     $ ssh-copy-id user@host

0
source share

All Articles