You are not logged in.
Hi,
I have no idea if a program that does the following exists. The concept is a bit hard to explain but I'll do my best.
Lets say that you have to terminals opened. In terminal 1 you are currently working in ~/build/foobar and in terminal 2 you are working in ~/archiscool/foobar/letshaveadrink/ and you want to copy a file from ~/build/foobar to ~/archiscool/foobar/letshaveadrink. The usual way of doing this would be to type
"[user@host ~/build/foobar/]$ cp foobar ~/archiscool/foobar/letshaveadrink/"
and it is usually very quick to do with completion, but it would be much easier if one could build a script (lets call it "t2dir") that could identify the working dir of terminal 2. Then you'd only have to type
"[user@host~/build/foobar/]$ cp foobar t2dir".
Would it possible to probe terminals for their working directories?
Last edited by Ashren (2008-04-17 09:47:00)
Offline
I bet you would need a kind of daemon that keeps track of all the terminals and their current working directory. So then you would be presented with multiple choices, a list of all the working directories of all open terminals, when pressing the TAB key twice, perhaps...
That's all I can think of, since I'm not a programmer...
Have you Syued today?
Free music for free people! | Earthlings
"Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away." -- A. de Saint-Exupery
Offline
I bet you would need a kind of daemon that keeps track of all the terminals and their current working directory. So then you would be presented with multiple choices, a list of all the working directories of all open terminals, when pressing the TAB key twice, perhaps...
That's all I can think of, since I'm not a programmer...
in fact, working directories are not associated to terminals, but to processes i.e. running instances of programs: each has its own - and not only shells like bash, but any else
there is a link /proc/123/cwd, which points to a working directory of a process , where 123 is the PID (known from the "ps" command)
this can help hacking this together...
may the Source be with you
Offline
Would be very cool if I could, e.g.:
$ cp this_file.txt /dev/pts/1
I point the file to my other terminal (pts/1), and then it finds what's the current working dir of pts/1 and copies the fle there.
Offline
freakcode, that's exactly the idea. Thanks for the pointers Danielsoft, I'll try to figure out how to do this. Suggestions and even working code are of course more than welcome.
Offline
I guess it can only be implemented:
- Using a daemon that keeps track of all your VCs and the current working dir. Then use a special copy command (say, "cpt <file> <term>") that does the job.
- Creating another shell that implements a method to handle cp to /dev/pts device files in a different way.
As most people have their favourite shell already (bash, dash, zsh, ...), I guess the first way is more feasible.
Edit: I'm thinking of using aliases and a daemon. I guess it will work good. Expect some hack here soon
Edit2: No daemon needed to track down the working dir. Danielsoft mentioned a simple way for finding it.
Last edited by freakcode (2008-04-18 00:36:42)
Offline
Great!
Offline
I guess it can only be implemented:
- Using a daemon that keeps track of all your VCs and the current working dir. Then use a special copy command (say, "cpt <file> <term>") that does the job.
- Creating another shell that implements a method to handle cp to /dev/pts device files in a different way.As most people have their favourite shell already (bash, dash, zsh, ...), I guess the first way is more feasible.
Edit: I'm thinking of using aliases and a daemon. I guess it will work good. Expect some hack here soon
don't forget the backtick mechanism: with that, you don't need a special cp nor special shell
cp file `pwd_of /dev/ptsX`
mv file `pwd_of /dev/ptsY`
where the command will return the path (we still don't know how) and the backticks would insert it into any other command
may the Source be with you
Offline
Where are these paths being stored? I'm really intrigued.
Offline
Here's something that will give the desired behaviour. You can put this script somewere on your PATH, and alias it to the "cp" command - it should behave just like the standard "cp" if you specify a directory instead of a terminal device as target, so it supersedes it.
I did it in Ruby because it's quick and simple, but the logic is simple, it should be reproducible even on plain shell scripting (with a lot more of pain, of course).
#!/usr/bin/ruby
if (ARGV.empty?) || (ARGV[0] == "-h") || (ARGV.size < 2)
STDERR.puts <<EOS
Usage: #{$0} [-h] <file> <target>
If <target> is a terminal device (under /dev/), the copy operation will occur
to the terminal current working dir. Otherwise, will be treated as a path.
EOS
exit 1
end
file = ARGV[0].to_s.strip
target = ARGV[1].to_s.strip
if File.directory? target
path = target
else
unless (pts = target.split("/dev/")[1])
STDERR.puts "Invalid target: #{target}"
exit 1
end
if (pid = `pgrep -n -t #{pts}`).empty?
STDERR.puts "Cannot determine pwd of device: #{pts}"
exit 1
end
path = `pwdx #{pid}`.split(": ")[1].strip
unless File.directory? path
STDERR.puts path
exit 1
end
end
`cp #{file} #{path}`
The script will identify nested shells inside a terminal. So, if you open a terminal, and then run another shell again, the script will assume the working dir from the innermost shell.
More test are welcome, maybe I forgot some error checking. I'm not sure how it behaves running under a non-Bash shell too.
Last edited by freakcode (2008-04-18 00:33:06)
Offline
This is so very cool. A very nice feature when file managing in a tiling window manager.
Thank you very much. Now I just have to switch over to awesome so I can have window titles with /dev/pts/X numbers on them.
Thanks again. I'll have to look into this ruby business now.
EDIT: Forgot to say that it works perfectly under bash btw. I'll do some more testing of course.
Last edited by Ashren (2008-04-17 23:42:52)
Offline
Well, you can display the pts in the title of a terminal window with this on .bashrc :
echo -n -e "\e]0;`tty`\a"
It's a good complement to this script, or a tilling WM.
And thanks for your idea, now it's a lot easier to copy files from one terminal working dir to another, I just need to specify the pts from the title bar.
Last edited by freakcode (2008-04-18 00:13:36)
Offline
Yay! I can stick with ol' faithful dwm. Thanks and you're welcome.
This thread shows just how great this community is IMO.
Offline
Wow! this is cool, I gotta try it out. Thanks a lot
Have you Syued today?
Free music for free people! | Earthlings
"Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away." -- A. de Saint-Exupery
Offline
To make copying even easier I made the following change to my .bashrc:
echo -n -e "\e]0;`tty`\a"
t0="/dev/pts/0"
t1="/dev/pts/1"
t2="/dev/pts/2"
t3="/dev/pts/3"
t4="/dev/pts/4"
t5="/dev/pts/5"
t6="/dev/pts/6"
So I can copy to a working directory with the following command: cpt foobar $t1
Last edited by Ashren (2008-04-18 12:32:55)
Offline
Here's an alternative: use `ls /dev/pts` to get a list of running ttys and present that list to the user and let them choose the destination. That way they won't have to know the "/dev/pts" number of the tty they want to copy to. It will be nice to people who use title-bar-less windows (like me).
#!/bin/sh
# Find out the PIDS of running ttys
PIDS=""
for PTS in $(ls /dev/pts); do
#echo "$PTS"
PID=$(pgrep -nt "pts/$PTS")
#echo "$PID"
if [ $PID != $$ ]; then
PIDS="$PIDS $PID"
fi
done
# Count the PIDS
i=0
for PID in $PIDS; do
i=$(($i + 1))
done
# Behave differently based on number of available destinations
case $i in
0)
echo "No other tty to copy to. Ignoring."
exit 1
;;
1)
DEST=$(pwdx $PIDS)
#echo "$DEST"
echo "Only one possible destination. Copying to $DEST."
exit $(cp "$1" "$DEST")
;;
*) # Many destinations
j=0
for PID in $PIDS; do
j=$(($j + 1))
echo "$j. $(pwdx $PID | sed -r -e's/^[0-9]+: //')"
done
echo "Select destination by entering its number (1, 2, etc.): "
read NUM
if [ $NUM -lt 1 ]; then
echo "Error: there is no number smaller than 1 in the list."
exit 2
elif [ $NUM -gt $j ]; then
echo "Error: there is no number greater than $j in the list."
exit 3
elif [ $NUM -gt 0 ] && [ $NUM -le $j ]; then
k=1
for PID in $PIDS; do
if [ $k -eq $NUM ]; then
DEST="$(pwdx $PID | sed -r -e's/^[0-9]+: //')"
exit $(cp "$1" "$DEST")
fi
k=$(($k + 1))
done
else
echo "Error: cannot understand what you wrote."
exit 4
fi
;;
esac
When in sh, I'm paranoid about spaces and metacharacters and globs and I don't know how to use arrays. I guess this explains the weird structure of the script.
It sucks that it doesn't check for duplicates when listing out possible destinations... I should write this in a more comfortable language like perl. But I should go do some real work now.
Last edited by peets (2008-04-18 14:39:04)
Offline
Furthermore,
alias cut='echo "$1" > ~/.cutbuffer'
alias paste='cp $(cat ~/.cutbuffer) $PWD'
but whatever's "cut" should be an absolute path.
Offline
Hi, my script lists pts number and current directory of this pts. It uses ls -l to get directory name from /proc/$PID/@cwd. I noticed it differs from peets' , it returns the pid of shell and not the pid of process running in that shell. It's an ugly script and it can be better, i know.
#! /bin/bash
set +x # for debug, + debug off, - debug on
for i in `ps ax | grep "pts.*$SHELL" | grep -v grep | sort | awk '{print $2 "_" $1}'`
do
PTS=`echo ${i/_*/} |sed 's/pts\///'`
PID=`echo ${i/*_/}`
echo "$PTS: `ls -l /proc/$PID/ | sed -n 's/.*cwd -> //p'`"
done
echo
read ptsnum
termpath=$(ls -l /proc/`ps ax | grep "pts/$ptsnum.*$SHELL" | grep -v grep | cut -d" " -f2`/ | sed -n 's/.*cwd -> //p')
if [ "$1" != "" -a "$termpath" != "" ]
then
echo -e "\nCopying $PWD/$1 to $termpath/$1"
cp "$1" "$termpath" && echo Done.
elif [ "$termpath" = "" ]
then
echo -e "\n/dev/pts/$ptsnum not found :("
fi
Offline