【问题标题】:`xdotool type ` - randomly repeats characters`xdotool type ` - 随机重复字符
【发布时间】:2012-07-09 05:36:00
【问题描述】:

我正在编写一个脚本来自动化工作环境准备。 我需要打开 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 处理,并且在脚本处理期间它的负载很高。

我在脚本中使用waitsleep 以及open_lxterminal_execute_hold() 函数调用的特殊顺序来首先执行简单的简单命令。这样可以最大限度地减少错误,但根本不会阻止它们。

无论 CPU 负载如何(无论如何),您建议如何获得稳定的结果?摆脱sleeps 也很棒。

#!/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重复字符?

【问题讨论】:

    标签: bash automation


    【解决方案1】:

    这是另一个解决方案,在我的 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”命令了。

    【讨论】:

    • 恩齐诺,感谢您的解决方案。但是 $SHELL 在获得 --rcfile 参数时不会执行 ~/.bashrc。这就是为什么我认为 ubuntu 的吸引力较小。
    • 我已经修改了脚本来执行~/.bashrc
    • 由于不需要 .bashrc 编辑,这种方式看起来更直接和干净。它也适用于 lxterminal。谢谢恩齐诺,谢谢ubuntu!我投票支持该解决方案。祝你好运!
    【解决方案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 的第一个值,而忽略了对其值的后续更改。

    【讨论】:

    • 当我使用 -e $command 时,终端在执行命令后退出。我需要终端机保持打开状态。
    • 好的,然后试试:lxterminal -t "$title" -e "bash -c '$command; read -n1'" &。我已经安装了 lxterminal 来测试它;它似乎对我有用。
    • 我明白了,它等待按键,然后关闭。我需要终端机保持打开状态。
    • 我看到你真的很想知道如何使用 xdotool 来解决这个问题。我不知道答案,但我想到了一个替代想法(使用 .bashrc),我认为它更好,所以我在上面发布。
    • unutbu,谢谢你的帮助。我意识到我真的不需要用 tail -f 命令打开那些终端,因为我不会打断它们。我只需要打开 2 个终端来输入命令以在不同的工作目录中执行它们。如果没有更好的答案出现,我将在 3 天内接受您的答案。 顺便说一句,如何快速来回切换工作目录?
    【解决方案3】:

    实际上我找到了另一个解决方案。我发现我使用了 ubuntu deb 包中的 2009 年的旧版本。我从源安装的最新版本的xdotool 允许一个新的命令行参数--delay <value>,如果与0 一起使用--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
    }
    

    祝大家好运!

    【讨论】:

      【解决方案4】:

      您可以改用xte 命令行工具。它做同样的工作,但没有随机键粘性。

      【讨论】:

        猜你喜欢
        • 2020-05-13
        • 1970-01-01
        • 1970-01-01
        • 2010-12-07
        • 2017-04-11
        • 2011-12-08
        • 2017-07-25
        • 2018-04-03
        相关资源
        最近更新 更多