2

在这个简单的脚本上

#!/bin/bash -i
trap 'echo "(ctrl+c was hit)"' INT
while true; do
    echo -n "hit Enter..";read
    echo "still on loop"
done

如果我按 ctrl+c 它将退出循环

如果我让它不与第一行交互#!/bin/bash,它会起作用!

问题是我有几个脚本(使用存储在的“启动应用程序”运行~/.config/autostart)只能在启用交互性的情况下正常工作#!/bin/bash -i,主要是因为它们加载了选项.bashrc授予的再次-i

有小费吗?

编辑:我在请求我的~/.bashrc文件时发现了这个:

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

这可以防止将该文件作为非交互式脚本中的源加载,我没有把它放在那里,我不知道它为什么在那里......

编辑:所以,由于问题是加载设置在的内容~/.bashrc,但脚本的行为并不奇怪,我发现由存储在的“启动应用程序”启动的脚本~/.config/autostart可能会以这种方式运行:

xterm -e "bash -i -c myScript.sh"
#or
bash -i -c 'xterm -e "myScript.sh"' #this way the title looks better

所以脚本不会有-i选项,只会从#!/bin/bash正常运行开始,并且~/.bashrc文件也会正确设置环境。

4

2 回答 2

2

让 bash 以交互方式运行可以启用作业控制、历史扩展、别名和其他一些您可能不希望在脚本中使用的东西,包括对信号行为的更改。

如果您只想从中加载变量~/.bashrc,您是否考虑过source ~/.bashrc

于 2013-07-04T00:11:04.687 回答
1

从 bash 手册页:

When  bash  is  interactive,  in  the  absence of any traps, it ignores
SIGTERM (so that kill 0 does not kill an interactive shell), and **SIGINT**
is  caught and handled (so that the wait builtin is interruptible). 

Crt-c 通常会发送 SIGINT(tty 驱动程序是控制 crt-c 做什么的驱动程序)。因此,bash 将在您的陷阱以交互模式调用后捕获 SIGNT。您可以尝试将该脚本中的 crt-c 映射到其他信号,然后捕获该信号(可能是 SIGTERM?)。

于 2013-07-03T22:21:01.080 回答