我正在编写一个脚本来自动化工作环境准备。 我需要打开4个终端窗口,排列它们并在每个窗口中执行命令。
它有效,但有时我讨厌失败 - xdotool type
随机重复某些字符:
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 >
或在其他窗口中:
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 >
我想这取决于CPU负载,因为我有非常大的.bashrc由ATOM处理,并且在脚本处理期间它的负载很高。
我在脚本中使用wait
和sleep
以及open_lxterminal_execute_hold()
函数调用的特殊顺序来首先执行简单的简单命令。这样可以最大限度地减少错误,但根本不会阻止它们。
无论CPU负载如何,您都建议获得稳定的结果(无论如何)?摆脱sleep
也是很好的。
#!/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
更新 如何防止xdotool重复charatcers?
答案 0 :(得分:2)
这是一个完全避免xdotool的解决方法。 从积极的方面来说,我认为这很简单。 从消极方面来看,它似乎不适用于lxterminal - 尽管它可以与其他终端一起使用,例如xterm和gnome-terminal。
对于它的价值,这是一个想法:
让bashrc根据title
环境变量的值运行相应的命令:
您可以通过在.bashrc中添加以下内容来实现:
case "$title" in
rails-development.log)
ls
;;
rails-commandline)
tail -fn 100 /var/log/syslog
;;
*)
;;
esac
然后在你的脚本中你可以使用
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 &
由于某些原因,lxterminal似乎只使用title
的第一个值,忽略了对其值的后续更改。
答案 1 :(得分:2)
这是另一个解决方案,在我的Ubuntu 11.04系统上测试并运行:
#!/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 &
正如您可能注意到的那样,我已经评论了一些测试行,因此您应该在系统上运行脚本之前从注释行中删除尾随的“#”。
我使用的技巧是在每个终端中启动一个带有“--rcfile”选项的新shell
这样,就不需要使用“xdotool”,“wait”和“sleep”命令。
答案 2 :(得分:0)
实际上我找到了一个解决方案。我发现我使用了ubuntu deb包的旧版2009年。我从源安装的xdotool
的最新版本允许使用新的命令行参数--delay <value>
,如果与--delay 0
一起使用,则会阻止重复字符。所以函数现在看起来如下:
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
}
祝你好运!
答案 3 :(得分:0)
您可以使用xte
命令行工具。它做同样的工作,但没有随机键粘性。