简体   繁体   English

如何在非交互式 bash 脚本及其 git 子程序中禁用 ctrl-c

[英]How to disable ctrl-c in a non-interactive bash script and its git subprograms

I am calling git clone from a non-interactive bash shell.我正在从非交互式 bash shell 调用 git clone。 It is non-interactive because it is launched from a Windows Explorer contect menu.它是非交互式的,因为它是从 Windows 资源管理器的连接菜单中启动的。 I am running git version 2.20.1.windows.1 on Windows 10 64-bit.我在 Windows 10 64 位上运行 git 版本 2.20.1.windows.1。

I am running Git/usr/bin/bash -l -e 'myscript' in a Git/usr/bin/mintty window launched from the context menu.我正在从上下文菜单启动的 Git/usr/bin/mintty 窗口中运行 Git/usr/bin/bash -l -e 'myscript' 。

I want to block the user from interrupting the git clone with ctrl-c.我想阻止用户使用 ctrl-c 中断 git clone。

I tried:我试过:

set -m
trap '' SIGINT SIGTERM (2 single quotes)
git clone ... &
wait -n
echo $?

The ctrl-c passes through to the git clone which exits. ctrl-c 传递到退出的 git clone。 I assume it has a signal handler that exits on SIGINT.我假设它有一个在 SIGINT 上退出的信号处理程序。 I would like to know why this does not work.我想知道为什么这不起作用。

I tried:我试过:

saved=$(stty -g)
stty -isig
git clone ...
stty "$saved"

The stty fails with "stty: standard input: Inappropriate ioctl for device" because there is no tty for a non-interactive bash shell. stty 因“stty:标准输入:设备的 ioctl 不合适”而失败,因为没有用于非交互式 bash shell 的 tty。 So how is the ctrl-c getting to the git clone if there is no tty?那么如果没有 tty,ctrl-c 是如何到达 git clone 的呢?

I am testing with git clone, but want to deploy this for git pull and git push.我正在使用 git clone 进行测试,但想为 git pull 和 git push 部署它。 Our developers have caused their local repos to be inconsistent by interrupting a long git pull with ctrl-c.我们的开发人员通过使用 ctrl-c 中断长时间的 git pull 导致他们的本地存储库不一致。

Any help would be appreciated.任何帮助,将不胜感激。

Processes that handle signals themselves (examples seem to be git , ping and scp ) prevent the parent trap from being called.自己处理信号的进程(例如gitpingscp )会阻止调用父trap

So this simple example won't fit these purposes:所以这个简单的例子不适合这些目的:

#!/bin/bash
trap '' SIGINT SIGTERM
sleep 10

This answer suggests using set -m (processes run in separate process group) in a subshell which does not send SIGINT to the the process:这个答案建议在不向进程发送 SIGINT 的子shell中使用set -m (进程在单独的进程组中运行):

#!/bin/bash
trap '' SIGINT SIGTERM
uninterruptableCommand="git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/"
( set -m; $uninterruptableCommand & wait )

WARNING: the example is a really long-running command.警告:该示例是一个真正长时间运行的命令。 You can still send signals to the process directly (eg pkill git ).您仍然可以直接向进程发送信号(例如pkill git )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM