我正在编写一个 bash 脚本,在其中假装打开一个新的终端窗口(在本例中为 gnome 终端),执行一些命令并更改终端窗口的标题。
为了更改终端窗口的标题,我正在使用该函数设置标题如提议的这个答案。当我手动打开一个新终端并在终端内输入时,该方法非常有效设置标题 MY_TITLE。但在这种情况下,从 bash 脚本中它不起作用,即使我来源这.bashrc文件。
#!/bin/bash
gnome-terminal -- /bin/bash -c "echo Hello from terminal 1; set-title Terminal 1; exec /bin/bash";
gnome-terminal -- /bin/bash -c "source ~/.bashrc; echo Hello from terminal 2; set-title Terminal 2; exec /bin/bash";
新打开的两个终端显示同样的错误:
/bin/bash: set-title: command not found
很明显bash解释器没有找到set-title这个函数,但是我不知道如何强制加载.bashrc打开 gnome 终端时的文件。
答案1
我将回答我自己的问题,但在解释我找到的两个解决方案之前,我将解释为什么我试图做的事情不起作用。
为什么我最初的方法是错误的
如果您的系统中有自定义功能~/.bashrc文件,就像我的例子中的文件一样设置终端窗口的标题,这些函数在从以自动方式执行命令的 bash 脚本打开的终端窗口中将不可用(如我的问题的示例)。
谢谢用户414777为提示。你是绝对正确的。我的 ~/.bashrc 文件开头包含以下代码:
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
通过打印选项标志,$-
结果是HB(正如预期的那样,这不是一个交互式外壳),所以显然set-title
我在结尾处拥有的功能~/.bashrc,永远不会被添加到 shell 中。
解决方案1(推荐):使用xfce4-terminal
作为薛迪杰的好奇心建议,这是解决该问题的最简单的方法。您可能不喜欢安装另一个终端工具;如果(就像我的情况一样)你使用的是 Gnome 并且默认使用 gnome-terminal,但好的一面是你可以使用xfce4-terminal
bash 脚本和gnome-terminal
“人机”交互,所以除了标题之外,你还可以使用额外的分类级别(如果您打开了许多终端窗口)。
它的xfce4-terminal
工作方式与 bash 脚本中的工作方式有点不同gnome-terminal
,但没有什么是你无法真正弄清楚的。无论如何,您都可以在下面找到解决方案xfce4-terminal
:
#!/bin/bash
xfce4-terminal --title "Terminal 1" -e "bash -c 'echo Hello from terminal 1; exec /bin/bash'" &
xfce4-terminal --title "Terminal 2" -e "bash -c 'echo Hello from terminal 2; exec /bin/bash'" &
解决方案 2:使用 xdotool
我发现该问题的另一个解决方案是使用xdotool
.xdotool
是一个命令行工具,可以在X11窗口系统中模拟/自动化人类交互。
这种解决方案过度设计了最初的问题,因为它会产生其他问题,例如 bash 脚本和 X windows 系统之间的同步,因此有必要sleep
在 bash 脚本中引入命令,以便为 X 窗口管理器提供时间来处理事件。这种同步问题使得该解决方案不可靠,因为它不能在 100% 的情况下工作,并且睡眠时间需要适应窗口系统的速度。
尽管我不建议针对问题中暴露的问题采用此解决方案,但我决定在答案中引入该解决方案以保证抖动完整性。其他人可能会发现将此方法应用于其他目的很有用:
#!/bin/bash
function set-title(){
sleep 0.2
# local WINDOW_ID=`xdotool getactivewindow`
# local P_ID=`xdotool getactivewindow getwindowpid`
# echo "the window id is: $WINDOW_ID with PID: $P_ID"
xdotool type "set-title $@"
xdotool key KP_Enter
sleep 0.2
}
gnome-terminal -- /bin/bash -c "echo Hello from terminal 1;echo $-; exec /bin/bash";
# xdotool search --onlyvisible --class 'gnome-terminal'
set-title "Terminal 1"
gnome-terminal -- /bin/bash -c "echo Hello from terminal 2; exec /bin/bash";
# xdotool search --onlyvisible --class 'gnome-terminal'
set-title "Terminal 2"
在这种情况下,该函数set-title
包含在~/.bashrc文件将起作用,因为在 中执行命令后gnome-terminal
,最后一条指令是/bin/bash
.它再次加载 shell,并使用 转发下一个命令到终端xdotool
,这会创建与人类使用输入设备(鼠标、键盘等)生成的事件相同的事件。