Reputation: 1508
I'm writing a script to automate work environment preparation. I need to open 4 terminal windows, arrange them and execute commands in each of them.
It works, but sometimes I get nasty fails - xdotool type
randomly repeats some characters:
rvm use ruby-1.99999999999999999999999999999999.3-p194@ro && rails c
~/my_src/ruby_apps/ro > rvm use ruby-1.99999999999999999999999999999999.3-p194@ro && rails c
ruby-1.99999999999999999999999999999999.3-p194 is not installed.
To install do: 'rvm install ruby-1.99999999999999999999999999999999.3-p194'
~/my_src/ruby_apps/ro >
or in the other window:
tail -fn 100 looooooog/thin.0.log
~/my_src/ruby_apps/ro > tail -fn 100 looooooog/thin.0.log
tail: could not open «looooooog/thin.0.log» for reading: No such file or directory
tail: no more files
~/my_src/ruby_apps/ro >
I guess it depends on CPU load, cause I have really big .bashrc processed by ATOM and its load is high during script processing.
I use wait
and sleep
and special order of open_lxterminal_execute_hold()
function invocations in the script toexecute simple simple commands first. That minimizes errors, but doesn't prevent them at all.
What would you suggest to get stable result regardless of CPU load(whatever)? It would be great to get rid of sleep
s as well.
#!/bin/bash
#
# prepares work environment for rails project
# Opens lxterminal with title if windows with such title
# doesn't exist, executes command and stays open.
# Otherwise does nothing.
#
function open_lxterminal_execute_hold(){
local winid=`xwininfo -name $title 2>/dev/null |grep 'Window id:' |cut -d" " -f4`
if [ -n "$winid" ]; then
echo "Window for title '$title' exists with '$winid'"
else
lxterminal -t $title
sleep 1
wmctrl -i -a "$winid" # bring the window to front, activate
wait
xdotool type "$command"
wait
xdotool key Return # run the command
wait
fi
}
pkill devilspie
cd ~/my_src/ruby_apps/ro # TODO param
title='rails-commandline'; command='ls'; open_lxterminal_execute_hold
title='rails-development.log'; command='tail -fn 100 log/development.log'; open_lxterminal_execute_hold
title='rails-user_case'; command='tail -fn 100 log/thin.0.log'; open_lxterminal_execute_hold
sleep 5
title='rails-console'; command='rvm use ruby-1.9.3-p194@ro && rails c'; open_lxterminal_execute_hold
/usr/bin/devilspie -a 2>/dev/null & # arrange windows
UPDATE How to prevent xdotool repeating charatcers?
Upvotes: 5
Views: 2381
Reputation: 288
You can use xte
command line tool instead. It does the same job, but without random key stickiness.
Upvotes: 0
Reputation: 1508
Actually I found anoter solution. I discovered that I used an old version of 2009 year from ubuntu deb package. The latest version of xdotool
I installed from sources allows a new command line param --delay <value>
which if used with 0 --delay 0
prevents repeating characters. So the function looks as follows now:
function open_lxterminal_execute_hold(){
local winid=`xwininfo -name $title 2>/dev/null |grep 'Window id:' |cut -d" " -f4`
if [ -n "$winid" ]; then
echo "Window for title '$title' exists with '$winid'"
else
lxterminal -t "$title"
sleep 1
wmctrl -i -a "$winid"
xdotool type --delay 0 "$command"
xdotool key Return
fi
}
good luck guys!
Upvotes: 0
Reputation:
Here is another solution, tested and working on my Ubuntu 11.04 system:
#!/bin/bash
function open_lxterminal_execute_hold() {
xwininfo -name $1 > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo "Window for title '$1' already exists"
else
t=$(tempfile)
echo ". ~/.bashrc" > $t
echo "$2" >> $t
lxterminal -t $1 -e "$SHELL --rcfile $t" &
fi
}
#pkill devilspie
#cd ~/my_src/ruby_apps/ro
open_lxterminal_execute_hold 'rails-commandline' 'ls'
open_lxterminal_execute_hold 'rails-development' 'tail -fn 100 log/development.log'
open_lxterminal_execute_hold 'rails-user_case' 'tail -fn 100 log/thin.0.log'
#open_lxterminal_execute_hold 'rails-console' 'rvm use ruby-1.9.3-pl94@ro && rails c'
#devilspie -a 2>/dev/null &
As you may notice, I've commented some lines for testing, so you should remove the trailing '#' from the commented lines before running the script on your system.
The trick I've used is to start in each terminal a new shell with the "--rcfile" option.
This way, there is no need to use the "xdotool", "wait" and "sleep" commands.
Upvotes: 2
Reputation: 880547
Here is a workaround which avoids xdotool altogether. On the positive side, I think it is fairly simple. On the negative side, it does not appear to work with lxterminal -- though it does work with other terminals such as xterm and gnome-terminal.
For what it's worth, here is the idea:
Let bashrc run the appropriate commands based on the value of the title
environment variable:
You can do so by adding something like the following to your .bashrc:
case "$title" in
rails-development.log)
ls
;;
rails-commandline)
tail -fn 100 /var/log/syslog
;;
*)
;;
esac
And then in your script you can use
function open_terminal_execute_hold() {
local winid=`xwininfo -name $title 2>/dev/null |grep 'Window id:' |cut -d" " -f4`
if [ -n "$winid" ]; then
echo "Window for title '$title' exists with '$winid'"
else
gnome-terminal -t "$title" &
fi
}
cd /tmp # TODO param
export title='rails-commandline' && open_terminal_execute_hold &
export title='rails-blah' && open_terminal_execute_hold &
export title='rails-development.log' && open_terminal_execute_hold &
For some reason lxterminal seems to only use the first value for title
, ignoring subsequent changes to its value.
Upvotes: 2