tags:

views:

686

answers:

3

Problem Not solved although one answer was accepted: We are working to get Jonah's code to work.

Problem: to change the code of (1) to (2)

I know the thread. I want to be able to run the following code inside Screen

Code (1)

cat ~/.vimrc | pbcopy                   (1)

Code (2)

cat ~/.vimrc > /tmp/pbcopy.pipe         (2)

My attempt to solve the problem: to put the following code to .zshrc

funtion pbcopy() { "(cat \"$1\")"  > /tmp/pbcopy.pipe }

I get

cat masi | pbcopy          
pbcopy: command not found: (cat "")
cat: masi: No such file or directory

How can you use pbcopy inside Screen?

+3  A: 

Alright, this is a screwy answer, but it is also a screwy question, so at least they match. You can create a named pipe with mkfifo, and then setup an infinite loop that reads files from the named pipe and pipes them to pbcopy (or xsel, xclip, etc.).

1. In a terminal which is NOT in a screen session (run this only once):

/usr/bin/mkfifo /tmp/pbcopy.pipe
while true; do /bin/cat /tmp/pbcopy.pipe | /usr/bin/pbcopy; done

You may want to turn this into a shell script like (this probably should be more robust)

#!/bin/bash

if [[ -e /tmp/pbcopy.pipe ]]; then
    echo "it looks like I am already running"
    echo "remove /tmp/pbcopy.pipe if you are certain I am not"
    exit 1
fi

while true; do
    /bin/cat /tmp/pbcopy.pipe | /usr/bin/pbcopy
done

which you can name pbcopy_server.sh, make executable (chmod a+x pbcopy_server.sh) and put somewhere in your path, so you can say nohup pbcopy_server.sh & when you first start your machine.

2. In any other terminal (including those in screen sessions) you can now cat files (or redirect output of programs into /tmp/pbcopy.pipe and the text will appear in the clipboard.

cat file > /tmp/pbcopy.pipe

df -h > /tmp/pbcopy.pipe

3. To make it look like you are calling the real pbcopy you can use something to do the cat'ing to /tmp/pbcopy.pipe for you.

3a. Use a zsh function:

function pbcopy() { cat > /tmp/pbcopy.pipe }

3b. Or create a Perl script named pbcopy and put it in a directory earlier in your PATH than /usr/bin:

#!/usr/bin/perl

use strict;
use warnings;

open my $out, ">", "/tmp/pbcopy.pipe"
   or die "could not open pipe to pbcopy: $!\n";

print $out $_ while <>;
Chas. Owens
How should your first command be used? Could you give an example?
Masi
I put Terminal A's code to one Screen session. I put Terminal B's code to another Screen session. Have I done correctly the start of your solution?
Masi
Doesn't the 'while true' loop eat alot of resources?
too much php
@Peter No, it is blocking on the read from the pipe, so no processor time is used until there is data in the pipe, when the pipe closes the while loop loops once and then you are blocking on the read from the pipe again. You are thinking of something like while true; do true; done which will eat one cpu. That consumes cpu because it executes true, loops, executes true, loops, etc. very rapidly. The solution to this is normally to put a sleep in the loop to slow it down, but we don't need one in this case because the blocking read will prevent the loop from looping.
Chas. Owens
@Masi Terminal A must not be running under screen. It needs access to pbcopy so it can give that access to the other shells that are running under screen. If you don't want a terminal lying around doing nothing, you could make that code a shell script into a daemon that you launch and forget about.
Chas. Owens
@Chas: Do you mean to put codes (1) and (2) in a file called pbcopyInScreen? Should I source the pbcopy.pl from the shell script?
Masi
1 should be run once in a normal shell or as a daemon before you start any screen sessions. 2 is just an example of how to use 1 once 1 is set up. 3 is a Perl script, it cannot be sourced by a shell, it is a command, it is analogous to your zsh function, so you can use either one. If you decide to use the Perl script you must make it executable with chmod a+x pbcopy and then put it somewhere in your PATH the is found before /usr/bin/pbcopy (so it executes when you say pbcopy instead of /usr/bin/pbcopy). I think the zsh function is probably a cleaner solution.
Chas. Owens
A: 

You may install an older version of Macport's screen which seems to solve this issue, as stated in comments of this article:
link to the last comment explaining how to do

I've tried myself and screen works very fine now with pbcopy ! :-)

Check that step:

  1. Install Macport using its DMG file. Leopard's DMG

  2. Launch a new Terminal and
    $ sudo vi /opt/local/etc/macports/sources.conf
    finally those 2 lines only remains in sources.conf, no more:

    file:///Users/xxxxx/ports
    rsync://rsync.macports.org/release/ports/ [default]

  3. $ cd
    $ mkdir -p ports/sysutils/
    (do not create a "screen" directory, svn will)

  4. $ cd ports/sysutils/
    $ svn co -r 45745 http://svn.macports.org/repository/macports/trunk/dports/sysutils/screen

  5. Once check out:

    $ cd $HOME/ports
    $ portindex
    Creating software index in /Users/keugaerg/ports Adding port sysutils/screen

    Total number of ports parsed:   1 
    Ports successfully parsed:  1  
    Ports failed:     0
    
  6. $ sudo port install screen (may take a while as downloading screen and buidling it)

Then it's done, just have to launch /opt/local/bin/screen .

yves Baumes
I did everything as you advised. However, I get the following error message http://dpaste.com/44754/. I apparently have the Screen in my MacBook that was shipped with Leopard currently. My Screen version is 4.00.03.
Masi
that's true , screen -v returns me the same version both for the Leopard pre-installed screen and the for the macoports one. But as far as I understood, people at Macports is sigtly modifing each sources from the linux project before they put it in the svn
yves Baumes
About your error , I only googled the error message and found that:http://trac.macports.org/ticket/18136Have a look, the person who created the ticket tell that its problem has been solved this way:"Problem solved: I upgraded to the latest version of Apple's developer tools."Do you have the latest one ?
yves Baumes
+1  A: 

There is a much easier solution to just use osascript as found at http://www.samsarin.com/blog/2008/10/18/copying-gnu-screen-buffer-to-leopard-clipboard/

In the comments, Andrew Wason provides this solution to copy the screen buffer:

Code in your .screenrc

# binds C-a b to copy the contents of your last screen copy to the MacOSX pasteboard
bind b eval "writebuf /tmp/screen-pbcopy" "exec /usr/bin/osascript -e 'tell application \"System Events\"' -e 'set the clipboard to (read posix file \"/tmp/screen-pbcopy\" as text)' -e 'end tell'"

Also using osascript, here's a bash script which emulates the behavior of pbcopy within screen. Improvements to this script are welcome:

Save this code as a bash script somewhere in your path, example: ~/bin/pbcopyScreen.bash

#!/bin/bash

# saves all standard input to a file
cat > /tmp/screen_pbcopy_kludge_buffer

# uses osascript to set the MacOSX pastebaord to the contents of the file
/usr/bin/osascript -e 'tell application "System Events"' -e 'set the clipboard to (read posix file "/tmp/screen_pbcopy_kludge_buffer" as text)' -e 'end tell'

rm /tmp/screen_pbcopy_kludge_buffer
Jonah Braun
It is hard for me to understand the last without an example. @How should I name it? @Where should I put it? It would make sense if the first code calls the last one in your message. @Where does the first code call the last code?
Masi
Yes, so the second script is just a simple bash script that you should put wherever you keep your personal scripts. The .screenrc entry uses writebuf to save the contents of it's copy buffer. The second bash script accepts standard input (like the original pbcopy), so it wouldn't make sense to have the first call the second.
Jonah Braun
I did not get the code to work. I tried the following code in my .screenrc % bind b eval "writebuf" "exec /Users/Masi/bin/pbcopyScreen.bash -c 'pbcopy < /tmp/screen-exchange'" % too. Please, paste some concrete examples about your pbcopy in Screen.
Masi
@Jonah: I also used a path at /usrl/local/bin unsuccessfully. I am not sure which one is the bug: pbcoping or pbpasting. % cat /screen-exchagne % shows no paste.
Masi
@Masi: I am using both scripts exactly as shown successfully in MaxOSX 10.5. In screen, use C-a [ to enter copy mode (as usual) and select the text to copy with the space bar. Afterwards, use C-a b to copy the text to the clipboard. Now in any application cmd-v will paste as usual. Side note: /tmp/screen-exchange won't show anything, the script specifies /tmp/screen-pbcopy
Jonah Braun