help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Help-bash] Automatically "disown -h" all background jobs


From: doark
Subject: [Help-bash] Automatically "disown -h" all background jobs
Date: Wed, 9 Aug 2017 23:45:30 -0400

On Tue, 1 Aug 2017 14:31:59 +0200
"R. Diez" <address@hidden> wrote:
> Hi all:
> 
> It happens to me all the time: I start a background GUI job with &,
> like "git gui &", I then close the terminal window with the mouse, and
> the GUI job is gone with it. However, quitting with "exit" leaves
> background jobs running fine. At least that is the default behaviour in
> many distros.
> 
> I know about SIGHUP, nohup, huponexit, disown, etc. But they do not 
> really help, or I just cannot remember to use the right one every time. 
> It's annoying.
> 
> I am not the only one who has noticed:
> 
> https://unix.stackexchange.com/questions/284673/automatically-disown-application-when-running-it-from-a-terminal
>
> But the proposed solution would mean having to remember something new, 
> and my muscle memory strongly disagrees.
>
> What I need is a new option in Bash to stop forwarding SIGHUP to 
> background jobs. The foreground job should still get it though.
> 
> I tried trapping SIGHUP for a while in .bashrc , but that left 
> foreground processes like "less </dev/null" running in the background 
> when I forcibly closed the Emacs multi-term frame Bash and 'less' were 
> running in. So completely blocking SIGHUP is not a good solution for
> all situations.
> 
> I am using PROMPT_COMMAND="disown -a -h" at the moment, but this trick 
> is not elegant enough for me. 8-)
> 
> Regards,
>    rdiez

As you may have noticed, bash does not automagically know which jobs you
want to be restricted from receiving SIGHUP; in fact, I can't think of
a single mind reading program for Linux (:
You could reprogram bash to treat the & operator differently, but that
would be a bit much I think.
So you have two choices:
1: You can remember to type any number of cool commands into the terminal
to achieve the affect your desire over and over again.
2: You can type those commands in once and be done with it.

I'd vote for 2. You can achieve this by something like this in .profile
or .bashrc:

8<-----8<-----8<-----8<-----8<-----
function a()
{
    nohup "$@" &> /dev/null &
    disown;
}

alias git-gui="a git gui "$@""
8<-----8<-----8<-----8<-----8<-----

Then you just have to create a list of gui programs you want to restrict
the delivery of SIGHUP to and assign aliases accordingly.
You could probably get a list of them from a menu generator program if
you do not want to enter them manually.

But then you might not want to remember to type "git-gui" instead of
"git gui":

8<-----8<-----8<-----8<-----8<-----
function a()
{
    nohup "$@" &> /dev/null &
    disown;
}

function git()
{
    if [ "$1" = "gui" ]; then
        a git "$@";
    else
        "$(which git)" "$@";
    fi
}
8<-----8<-----8<-----8<-----8<-----

I've tested this on zsh and busybox's sh (which is actually ash). Busybox
does not have the disown command and my system does not have a dedicated
version.
zsh's which(1) command returns the function instead of the path to the git
command when using it's default configuration, but there might be a way
to change this. 
Therefore, this is bash specific, though I can't think of a good reason
why zsh and busybox would find it necessary to be incompatible.
I thought I might do something like "which which", but that returns
"which: shell built-in command" (Argh, you can't trust anybody these
days).

Personally, I think that sending the output of gui programs to /dev/null
is not a very good idea because then if something goes wrong with the
gui program you never really know what that something is. This is my
number 1 complaint against desktop environments.
So (mkdir ~/.logs/)....

8<-----8<-----8<-----8<-----8<-----
function a()
{
    nohup "$@" &> "/home/$USER/.logs/""$1""-log.txt" &
    disown;
}

function git()
{
    if [ "$1" = "gui" ]; then
        a git "$@";
    else
        "$(which git)" "$@";
    fi
}
8<-----8<-----8<-----8<-----8<-----

Of course, this still does not handle the case where you have more than
one of a program running via the terminal (a good example would be
multiple invocations of xterm)...

8<-----8<-----8<-----8<-----8<-----
function a()
{
    nohup "$@" &> \
    "$(mktemp -u "/home/$USER/.logs/""$1""-XXXXXXX-log.txt")" & disown;
}

function git()
{
    if [ "$1" = "gui" ]; then
        a git "$@";
    else
        "$(which git)" "$@";
    fi
}
8<-----8<-----8<-----8<-----8<-----

Phew, I've suddenly decided to retire from shell scripting for a
fortnight.
Have fun with whatever it is that you're trying to do by posting lots of
sh related questions.
BTW: Do you have a martyr complex?  (:


Sincerely,
David

Attachment: pgpZT6ArJ_xHL.pgp
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]