LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 01-15-2011, 01:45 PM   #1
Ishrimak
LQ Newbie
 
Registered: Jan 2011
Posts: 2

Rep: Reputation: 0
Bash script - obtain current workdirs of all konsole terminal/sessions


Hello there,

I am trying to write a bash script that would save the current state of my konsole terminals and sessions. I'm using KDE3.X and for some reason the "profile" save does not save the current working directories...

Anyway, I would like to know if there is an elegant way to obtain the current workdir of each terminal and session ?

I've managed to do something with a clever use of DCOP extended functions, but it requires me to start every konsole with the --script option enabled, and I don't want to do that.

Any help would be greatly appreciated !

Cheers
 
Old 01-16-2011, 09:31 AM   #2
unSpawn
Moderator
 
Registered: May 2001
Posts: 29,415
Blog Entries: 55

Rep: Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600
A process has a uniqe Process Id or PID ('pgrep konsole' or 'pidof konsole'). The $CWD is the link at /proc/$(pgrep konsole)/cwd. The value you can read like 'readlink -f /proc/$(pgrep konsole)/cwd' but be aware that for multiple PIDs you want to use something like 'pgrep konsole|while read PROC; do readlink -f /proc/$PROC/cwd; done;'.
 
Old 01-16-2011, 07:59 PM   #3
cin_
Member
 
Registered: Dec 2010
Posts: 281

Rep: Reputation: 24
throw() hurl()

I thought this was a completely reasonable request, and was amazed that my research came up null on a prefab solution.
I wrote some scripts to work this process...

anam()
Code:
# anam -h
usage: anam prints working directory to session log
usage : anam parameters 
-n : new : creates new flux session log
-a : append : adds current instance to flux session
-ns [1-9] : new session : creates a new dedicated session
-as [1-9] : append session : appends a dedicated session
-h : helper : opens this help dialogue
add extra parameter : e : to feel Oedipal, and kill your parent process, terminating the terminal, after logging the session instance 
#
This script, depending on argument, prints the terminal's working directory to a log file.
The -as and -ns parameters are of particular note. If you have a session you always use, save it to its own dedicated log for continued reuse.

... you can edit the Flux Variables to suit your tastes...
/src
Code:
#!/bin/bash
###FLUX VARIABLES#################
LOG_DIR="/var/log/"            ###  
NM="ptswd"                     ###  
##################################
append ()
{
	if [ $2 ]; then
		FILE="$LOG_DIR$NM.session$2"
	else
		FILE=$LOG_DIR$NM
	fi
if [ -e $FILE ]; then
TTY_MEM=( $( cat $FILE ) )
TTY_MNUM=${#TTY_MEM[@]}
TTY_NM=`tty`
else
	touch $FILE; chmod a+w $FILE;
	TTY_MEM=( $( cat $FILE ) )
	TTY_MNUM=${#TTY_MEM[@]}
	TTY_NM=`tty`
fi

ALT=0
IND=0
while [ $IND -lt $TTY_MNUM ]; do
	if [ "$TTY_NM" == "${TTY_MEM[$IND]}" ]; then
		ALT=17
		TTY_MEM[$IND+1]=$PWD
	fi
let IND=IND+1
done

IND=0
if [ $ALT -eq 17 ]; then
	cat /dev/null > $FILE
while [ $IND -lt $TTY_MNUM ]; do
	echo "${TTY_MEM[$IND]}" "${TTY_MEM[$IND+1]}" >> $FILE
let IND=IND+2
done
else
	echo "$TTY_NM" "$PWD" >> $FILE
fi
}

new () { N_FILE=$LOG_DIR$NM; if [ $2 ]; then N_FILE="$LOG_DIR$NM.session$2"; touch $N_FILE; chmod a+w $N_FILE; cat /dev/null > $N_FILE; else touch $N_FILE; chmod a+x $N_FILE; cat /dev/null > $LOG_DIR$NM; fi; }

helper () { echo -e "usage: `basename $0` prints working directory to session log\nusage : `basename $0` parameters \n-n : new : creates new flux session log\n-a : append : adds current instance to flux session\n-ns [1-9] : new session : creates a new dedicated session\n-as [1-9] : append session : appends a dedicated session\n-h : helper : opens this help dialogue\nadd extra parameter : e : to feel Oedipal, and kill your parent process, terminating the terminal, after logging session"; }

e3x17 () { if [ "$3" == "e" -o "$2" == "e" -o "$1" == "e" ]; then TTY_PID=( $( echo -e `ps h T | cut -c1-6` ) ); TTY_KILL=`ps -p ${TTY_PID[0]} -o ppid=`; kill $TTY_KILL; fi; }

if [ $# -le 3 ]; then
	if [ $3 ]; then
	case "$3" in
		"e");;
		*) helper;;
	esac
	fi
	if [ $2 ]; then
	if [ "$1" == "-as" -o "$1" == "-ns" ]; then	
		case "$2" in
			[0-9]) ;;
			*) helper ;;
		esac
	else
		case "$2" in
		"e");;
		*) helper;;
		esac
	fi
	fi
	case "$1" in
		"") append;;
		"e") append; e3x17 $1;;
		"-a") append; e3x17 $2;;
		"-as") append $1 $2; e3x17 $3;;
		"-n") new; append; e3x17 $2;;
		"-ns")new $1 $2; append $1 $2; e3x17 $3;;
		"-h") helper;;
		*) echo "usage: `basename $0` prints working directory to session log. type `basename $0` -h for help"
	esac
else
	helper
fi
noesis()
Code:
# noesis -h
usage : noesis prints working directories to the flux session log of all open pseudo terminal slaves
EXAMPLE : noesis "COMM ARG1 ... ARGn" : if your command has arguments place the entire command in quotes
#
If you have a number of terminals open, and you want to log them all in one go... this is the command to do it.

/src
Code:
#!/bin/bash
###FLUX VARIABLES#################
LOG_DIR="/var/log/"            ###
NM="ptswd"                     ###
##################################
FILE=$LOG_DIR$NM
cat /dev/null > $FILE
IND=1
helper () 
{ echo -e "usage : `basename $0` prints working directories to the flux session log of all open pseudo terminal slaves\nEXAMPLE : `basename $0` \"COMM ARG1 ... ARGn\" : if your command has arguments place the entire command in quotes"; }

gnostic ()
{
echo -e `who | cut -c10-17` > "/tmp/CURR_WHO"
OP_PTS=( $( cat /tmp/CURR_WHO ) )
rm /tmp/CURR_WHO

while [ $IND -lt ${#OP_PTS[@]} ] ; do
	`throw "/dev/""${OP_PTS[$IND]}" "$COMM"`
let IND=IND+1
done
}
if [ $# -gt 0 ]; then
	if [ $# -le 1 ]; then
	case "$1" in
		"-h") helper;;
		*) COMM=$1; gnostic;;
	esac
	fi
else
helper
fi

anamnesis()
Code:
# anamnesis -h
usage : anamnesis recalls a called session from its log file
EXAMPLE : anamnesis LOG_FILENAME : send filename of logged session to recall
DIR : see anam() source for directory and file names
-h : helper : calls this help dialogue
#
This will recall all of the terminals and redirect their working directory to the ones stored in the called log.
For best results run this from the first instance, /dev/pts/0, with no other terminals running. That way the newly opened terminals will be the ones that are redirected as per the log.

...match your directory
...choose your preferred terminal
...fine tune the sleep command for a more seamless transition... My obsessions in mathematics far outweigh my impatience...
/src
Code:
#!/bin/bash
###FLUX VARIABLES#################
LOG_DIR="/var/log/"            ###
PREF_TERM="rxvt"	       ###
##################################
helper () { echo -e "usage : `basename $0` recalls a called session from its log file\nEXAMPLE : `basename $0` LOG_FILENAME : send filename of logged session to recall\nDIR : see anam() source for directory and file names\n-h : helper : calls this help dialogue\n"; }

resession () {
IND=1;
HYP_PTS=( $( cat $LOG_DIR$1 ) )
HYP_PTSn=${#HYP_PTS[@]}
let PTS_IND=$(($HYP_PTSn/2))+1
TERMS=$PTS_IND
while [ $IND -le ${#HYP_PTS[@]} ]; do
{
	screen -d -m $PREF_TERM -e bash
let IND=IND+2;
let TERMS=$TERMS+1
}
done

sleep 17;

IND=1
while [ $PTS_IND -lt $TERMS ]; do
{
	throw "/dev/pts/$PTS_IND" "cd ${HYP_PTS[$IND]}"
let IND=$IND+2
let PTS_IND=$PTS_IND+1
}
done
} 

if [ $# -eq 1 ]; then
case "$1" in
	"") helper;;
	"-h") helper;;
	*) resession $1;;
esac
else
	helper
fi
You had said Bash, and I tried to get it all done in Bash, but this next part was requiring some severe acrobatics. I turned to C...

throw()
Code:
# throw -h
usage : throw : sends a command to another open psuedo terminal slaves to session log
usage : throw : throw DEVICE_NAME COMMAND 
usage : throw : EXAMPLE : throw /dev/pts/1 who
#
This script comes with a partner: hurl(); essentially a quick and easy rewrite of noesis() that allows you to throw() to all open psuedo terminals.

/src
Code:
//main() with args
#include <stdio.h>
//malloc(),realloc()
#include <stdlib.h>
//open(), close()
#include <unistd.h>
//O_RDWR
#include <fcntl.h>
//ioctl(), TIOCSTI
#include <sys/ioctl.h>
//strlen , strcat
#include <string.h>

int main (int argc, char *argv[])
{
    int i, 
	fd = 0, 
	BASE_ARG = 0,
	DEV_ARG = 1,
	COMM_ARG = 2,
        RET_ARG = 3,	
	MEM_LEN = 0;
    char *COMM,
	 *BASE_NM = argv[BASE_ARG],
	 *DEV_NM = argv[DEV_ARG],
	 *RET = "\n";
   if (argc < 3 || argc > 4)
   {
	printf("usage : %s : sends a command to another open psuedo terminal slaves to session log\n", BASE_NM);
	printf("usage : %s : %s DEVICE_NAME COMMAND \n", BASE_NM, BASE_NM);
	printf("usage : %s : EXAMPLE : %s /dev/pts/17 who\n", BASE_NM, BASE_NM);
   }
   if ( argc > 1 ) 
   {
        COMM = argv[COMM_ARG];
   } else {
        printf("usage : %s : No command passed\n", BASE_NM);
	exit (0);
   }


   fd = open(argv[DEV_ARG], O_RDWR);
	if (fd == -1)
	{
		printf("usage : %s : device %s not open\n", BASE_NM, DEV_NM);
	}
	for ( i = COMM_ARG; i < argc; i++ )
	{
	MEM_LEN += strlen(argv[i]) + 2;
	if( i > COMM_ARG )
	{
	COMM = (char *)realloc((void *)COMM, MEM_LEN);
	} else
	{	
	COMM = (char *)malloc(MEM_LEN);
	}

	strcat(COMM, argv[i]);
	strcat(COMM, " ");
	}
  
   for (i = 0; COMM[i]; i++) {
        ioctl (fd, TIOCSTI, COMM+i); }
        
   ioctl (fd, TIOCSTI, RET);
   close(fd);
   exit (0);
}
Save this code to FILENAME.c, and then run...
either ...
Code:
make FILENAME_WITHOUT_EXTENSION
or...
Code:
# gcc FILENAME.c -o FILENAME_WITHOUT_EXTENSION
Finally, to be able to use these tools what you can do is place them all in a folder of your choosing, after compiling and chmod a+x'ing, and then add that folder to your PATH...
Code:
# PATH=$PATH:/dir/to/scripts
be good

Last edited by cin_; 01-22-2011 at 01:29 AM. Reason: gramm'err
 
Old 01-17-2011, 06:18 AM   #4
Ishrimak
LQ Newbie
 
Registered: Jan 2011
Posts: 2

Original Poster
Rep: Reputation: 0
Thanks a lot for your answers !

@unSpawn: I tried to go your way first, and I have to say I had no idea about the "pgrep" function, which might come handy in many situations. However, all the konsole processes that pgrep gives me have cwd linked to my homedir. More, I cannot find any information on the different sessions that I may have open in each konsole.

@_cin: WOW! You probably spent a lot of time writing these programs/scripts, and I thank you for that. I am going to take some time to fully understand what you wrote, and I'm sure I am going to learn a lot in the process...
 
Old 01-17-2011, 04:05 PM   #5
unSpawn
Moderator
 
Registered: May 2001
Posts: 29,415
Blog Entries: 55

Rep: Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600
Quote:
Originally Posted by Ishrimak View Post
all the konsole processes that pgrep gives me have cwd linked to my homedir. More, I cannot find any information on the different sessions that I may have open in each konsole.
"Sessions" in this case may be a concept only konsole knows how to deal with internally meaning there is no DE-agnostic way to determine anything.
 
Old 01-17-2011, 06:47 PM   #6
cin_
Member
 
Registered: Dec 2010
Posts: 281

Rep: Reputation: 24
Mi Piace

My pleasure.
I have more work to do on them yet. I want to be screen() and who() independent, so I will have to study their source for some insight and suggestion into my own desired functionality...

Thank you; it was a great idea.
I learned a lot in making these, and had a lot of fun as well.

I always have more fun on the forums looking for questions than answers.

Last edited by cin_; 01-17-2011 at 06:47 PM. Reason: gramm'err
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Using script to automatically record terminal sessions when a user logs in johnbolton Linux - General 10 02-22-2018 08:33 PM
Referring to the Current Terminal in a Bash Script? Daedagnir Programming 4 12-24-2010 10:36 AM
Bash script to test for open FTP sessions from specific clients dz-015 Programming 7 04-09-2009 06:33 AM
Obtain ip address and check for running process via Bash Script? xconspirisist Programming 10 09-12-2008 01:18 PM
Bash: set Konsole window title to current command bforbes Programming 5 04-19-2006 11:44 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 08:42 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration