2009-03-23 11:59:25 +0000 2009-03-23 11:59:25 +0000
311
311

Hoe maak ik een proces volledig los van de terminal?

Ik gebruik Tilda (drop-down terminal) op Ubuntu als mijn “commandocentrale” - ongeveer zoals anderen GNOME Do, Quicksilver of Launchy zouden kunnen gebruiken.

Maar ik heb moeite met hoe ik een proces (bijv. Firefox) volledig kan loskoppelen van de terminal van waaruit het is gestart - d.w.z. voorkomen dat zo'n (niet-)kinderproces

  • wordt beëindigd bij het sluiten van de oorspronkelijke terminal
  • de oorspronkelijke terminal via STDOUT/STDERR

“vervuilt” Om bijvoorbeeld Vim in een “goed” terminalvenster te starten, heb ik een eenvoudig script als het volgende geprobeerd:

exec gnome-terminal -e "vim $@" &> /dev/null &

Echter, dat veroorzaakt nog steeds vervuiling (ook het doorgeven van een bestandsnaam lijkt niet te werken).

Antworten (18)

355
355
355
2009-03-23 13:18:35 +0000

Eerst en vooral; als je eenmaal een proces hebt gestart, kun je het op de achtergrond zetten door het eerst te stoppen (druk op Ctrl-Z) en dan op bg te typen om het op de achtergrond te laten hervatten. Het is nu een “job”, en zijn stdout/stderr/stdin zijn nog steeds verbonden met uw terminal.

U kunt een proces als achtergrond starten door een “&” toe te voegen aan het einde ervan:

firefox &

Om het op de achtergrond tot zwijgen te brengen, gebruik je dit:

firefox </dev/null &>/dev/null &
  • *

:

nohup is een programma dat je kunt gebruiken ** om je applicatie te draaien met** zodat de stdout/stderr in plaats daarvan naar een bestand kan worden gestuurd en zodat het sluiten van het ouderscript het kind niet zal SIGHUPen. U moet echter wel de vooruitziende blik hebben gehad om het te kunnen gebruiken voordat u de applicatie start. Vanwege de manier waarop nohup werkt, kunt u het niet gewoon toepassen op een lopend proces.

disown is een bash builtin die een shell-job uit de takenlijst van de shell verwijdert. Wat dit in principe betekent is dat je fg, bg er niet meer op kunt gebruiken, maar wat nog belangrijker is, als je je shell sluit zal het niet meer hangen of een SIGHUP naar dat kind sturen. In tegenstelling tot nohup, wordt disown gebruikt na het proces is gestart en op de achtergrond geplaatst.

Wat je kan niet doen, is de stdout/stderr/stdin van een proces veranderen nadat je het hebt gestart. Tenminste niet vanuit de commandoregel. Als je je proces start en zegt dat de stdout je terminal is (wat je standaard doet), dan wordt dat proces geconfigureerd om naar je terminal uit te voeren. Uw shell heeft niets te maken met de FD-setup van de processen, dat is puur iets wat het proces zelf beheert. Het proces zelf kan beslissen of het zijn stdout/stderr/stdin sluit of niet, maar u kan uw shell niet gebruiken om het te forceren.

Om de uitvoer van een achtergrondproces te beheren, hebt u tal van opties van scripts, “nohup” is waarschijnlijk de eerste die in gedachten komt. Maar voor interactieve processen begin je maar vergeet je te zwijgen (firefox < /dev/null &>/dev/null &) kun je niet veel doen, echt waar.

Ik raad je aan om GNU screen te krijgen. Met het scherm kun je gewoon je draaiende shell sluiten als de uitvoer van het proces een last wordt en een nieuwe openen (^Ac).

  • *

Oh, en trouwens, gebruik “$@” niet waar je het gebruikt.

$@ betekent, $1, $2, $3 …, wat je commando zou veranderen in:

gnome-terminal -e "vim $1" "$2" "$3" ...

Dat is waarschijnlijk niet wat je wilt, want -e neemt slechts een argument. Gebruik $1 om te laten zien dat je script maar één argument kan verwerken.

Het is echt moeilijk om meerdere argumenten goed te laten werken in het scenario dat je gaf (met de gnome-terminal -e) omdat -e maar één argument neemt, wat een shell commando string is. Je zou je argumenten moeten coderen tot één. De beste en meest robuuste, maar nogal cludgy, manier is als volgt:

gnome-terminal -e "vim $(printf "%q " "$@")"
202
202
202
2009-03-23 12:17:32 +0000
nohup cmd &

nohup maakt het proces volledig los (daemoniseert het)

62
62
62
2009-03-23 12:05:02 +0000

Als u bash gebruikt, probeer dan disown [jobspec]; zie bash(1) .

Een andere benadering die u kunt proberen is at now. Als u geen superuser bent, kan uw toestemming om at te gebruiken beperkt zijn.

41
41
41
2014-01-22 17:08:16 +0000

Bij het lezen van deze antwoorden kreeg ik de eerste indruk dat het uitgeven van nohup <command> & voldoende zou zijn. Lopend zsh in gnome-terminal, vond ik dat nohup <command> & niet verhinderde dat mijn schil het doden van kind processen bij de uitgang. Hoewel nohup nuttig is, vooral bij niet-interactieve shells, garandeert het dit gedrag alleen als het kinderproces zijn handler niet reset voor het SIGHUP signaal.

In mijn geval had nohup moeten voorkomen dat hangup signalen de applicatie bereikten, maar de kinderapplicatie (VMWare Player in dit geval) was zijn SIGHUP handler aan het resetten. Als gevolg daarvan kon de terminal emulator bij het verlaten van de applicatie nog steeds je subprocessen uitschakelen. Dit kan alleen worden opgelost, voor zover ik weet, door ervoor te zorgen dat het proces wordt verwijderd uit de jobtabel van de shell. Als nohup wordt overruled met een ingebouwde shell, zoals soms het geval is, kan dit echter voldoende zijn, in het geval dat het niet…

  • *

disown is een ingebouwde shell in bash, zsh, en ksh93,

<command> &
disown

of <command> &; disown

als je de voorkeur geeft aan one-liners. Dit heeft het algemeen gewenste effect van het verwijderen van het subproces uit de klussenlijst. Hierdoor kunt u de terminal emulator verlaten zonder per ongeluk het kinderproces te signaleren. Hoe de SIGHUP handler er ook uitziet, dit zou het kinderproces niet moeten doden.

Na de disown is het proces nog steeds een kind van je terminal emulator (speel met pstree als je dit in actie wilt zien), maar na de uitgang van de terminal emulator zou je het moeten zien vastzitten aan het init-proces. Met andere woorden, alles is zoals het zou moeten zijn, en zoals je vermoedelijk wilt.

Wat moet je doen als je shell disown niet ondersteunt? Ik zou er sterk voor pleiten om over te stappen op een die dat wel doet, maar bij gebrek aan die optie heb je een paar keuzes.

  1. screen en tmux kunnen dit probleem oplossen, maar het zijn veel zwaardere oplossingen, en ik heb er een hekel aan om ze voor zo'n eenvoudige taak te moeten draaien. Ze zijn veel geschikter voor situaties waarin je een tty wilt onderhouden, meestal op een machine op afstand.
  2. 2. Voor veel gebruikers kan het wenselijk zijn om te zien of je shell een mogelijkheid als zsh’s setopt nohup ondersteunt. Dit kan gebruikt worden om aan te geven dat SIGHUP niet naar de jobs in de jobtabel gestuurd moet worden als de shell afgesloten wordt. U kunt dit toepassen vlak voor het verlaten van de shell, of het toevoegen aan de shellconfiguratie zoals ~/.zshrc als u het altijd aan wilt hebben.
  3. 3. Zoek een manier om de vacaturetabel te bewerken. Ik kon geen manier vinden om dit te doen in tcsh of csh, wat enigszins verontrustend is.
  4. 4. Schrijf een klein C-programma voor de fork off en exec(). Dit is een zeer slechte oplossing, maar de bron zou slechts uit een paar dozijn regels moeten bestaan. Je kunt dan commando’s als commandoregelargumenten doorgeven aan het C-programma, en zo een processpecifieke invoer in de jobtabel vermijden.
30
30
30
2015-08-25 14:39:31 +0000
  1. nohup $COMMAND &
  2. $COMMAND & disown
  3. setsid command

Ik gebruik al heel lang nummer 2, maar nummer 3 werkt net zo goed. Ook heeft disown een nohup vlag van -h, kan alle processen met -a uitschakelen, en kan alle lopende processen met -ar uitschakelen.

Silencing wordt bereikt door $COMMAND &>/dev/null.

Hoop dat dit helpt!

9
9
9
2017-05-05 11:55:05 +0000

Het meest eenvoudige en enige juiste antwoord voor bash:

command & disown

Je hoeft het proces niet los te koppelen van de terminal, maar van de schil.

9
9
9
2009-03-23 14:55:15 +0000

in tcsh (en misschien ook in andere shells), kun je haakjes gebruiken om het proces los te maken.

Vergelijk dit:

> jobs # shows nothing
> firefox &
> jobs
[1] + Running firefox

Met dit:

> jobs # shows nothing
> (firefox &)
> jobs # still shows nothing
>

Dit verwijdert firefox van de klussenlijst, maar het is nog steeds gebonden aan de terminal; als je ingelogd bent op deze node via ‘ssh’, zal het proberen uit te loggen het ssh-proces nog steeds hangen.

7
7
7
2012-08-07 05:18:25 +0000

Om tty shell te dissociëren run commando door sub-shell voor b.v.

(commando)&

Wanneer uitgang gebruikte terminal gesloten is maar proces nog leeft.

check - (sleep 100) & exit

Open andere terminal

ps aux | grep sleep

Process is nog in leven.

5
5
5
2013-05-22 23:00:56 +0000

Achtergrond en voorgrond een klus is waarschijnlijk een van de allereerste dingen die elke Unix sys-admin zou moeten weten.

Hier is hoe het gedaan wordt met bash:

./script.sh
# suspend process
{ctrl-Z}
# background process
bg
# list all backgrounded jobs
jobs
# bring it back to foreground
fg
4
4
4
2009-03-23 12:03:50 +0000

Je kunt je commando uitvoeren met het nohup commando, dit ontkoppelt je proces en stuurt uitgangen om naar een bepaald bestand… maar ik weet niet zeker of dat precies is wat je nodig hebt…

2
2
2
2018-02-05 16:14:17 +0000

Voeg dit toe in uw bashrc/zshrc:

detach() {
  "$@" 1>/dev/null 2>/dev/null &; disown
}

Dan kunt u ontkoppelde commando’s als deze uitvoeren:

detach gedit ~/.zshrc
2
2
2
2009-03-23 12:10:49 +0000

Probeer daemon – moet beschikbaar zijn bij uw vriendelijke pakketbeheerder en zorg ervoor dat u zich op alle mogelijke manieren van de terminal kunt losmaken.

1
1
1
2015-06-14 17:53:47 +0000

In mijn .bashrc heb ik precies voor dat doel deze functies:

function run_disowned() {
    "$@" & disown
}

function dos() {
    # run_disowned and silenced

    run_disowned "$@" 1>/dev/null 2>/dev/null
}

Prefix een commando met dos om het los van de terminal te draaien.

De functie is geschreven om te werken met bash en zsh.

0
0
0
2010-06-19 16:46:44 +0000

Ik heb op Mac OS X gevonden dat ik zowel nohup EN disown moet gebruiken om ervoor te zorgen dat het kinderproces niet wordt afgebroken met de terminal.

0
0
0
2014-09-21 04:42:43 +0000

Ik gebruik het volgende script om dit te doen. Het stopt het printen van het proces naar de terminal, maakt het los met nohup, en verlaat het met de return status als het commando eindigt binnen de TIMEOUT.

#!/bin/bash

TIMEOUT=0.1

CMD=( "$@" )
#Could have some shortcuts here, e.g. replace "somefile.c" with "gedit somefile.c"

#use nohup to run the command, suppressing its output and allowing the terminal to be closed
#also send nohup's output to /dev/null, supressing nohup.out
#run nohup in the background so this script doesn't block
#print the command for debugging and to see bash variable expansion
printf "%q " "${CMD[@]}"
echo
nohup "${CMD[@]}" >/dev/null 2>&1 &
NOHUP_PID=$!

#kill this script after a short time, exiting with success status - command is still running
#this is needed as there is no timeout argument for `wait` below
MY_PID=$$
trap "exit 0" SIGINT SIGTERM
sleep $TIMEOUT && kill $MY_PID 2>/dev/null & #ignore "No such process" error if this exits normally

#if the command finishes before the above timeout, everything may be just fine or there could have been an error
wait $NOHUP_PID
NOHUP_STATUS=$?
#print an error if there was any. most commonly, there was a typo in the command
[$NOHUP_STATUS != 0] && echo "Error: $CMD"
#return the exit status of nohup, whatever it was
exit $NOHUP_STATUS

Gebruiksvoorbeeld:

>>> run false
false
Error: false
>>> echo $?
1
>>> run true
true
>>> run sleep 10
sleep 10
>>>
0
0
0
2019-06-21 07:14:46 +0000

sudo apt install ucommon-utils

pdetach command

Daar ga je :)

-1
-1
-1
2017-02-15 04:16:48 +0000

Veel antwoorden suggereerden het gebruik van nohup. Ik stel voor om pm2 te gebruiken. Het gebruik van pm2 in plaats van nohup heeft vele voordelen, zoals het in leven houden van de applicatie, het bijhouden van logbestanden voor de applicatie en nog veel meer andere functies. Voor meer details bekijk dit in .

Om pm2 te installeren moet u npm downloaden. Voor Debian gebaseerde systeem

sudo apt-get install npm

en voor Redhat

sudo yum install npm

of u kunt deze instructie volgen. Na het installeren van npm gebruik het om pm2

npm install pm2@latest -g

te installeren Zodra het klaar is kunt u uw toepassing starten via

$ pm2 start app.js # Start, Daemonize and auto-restart application (Node)
$ pm2 start app.py # Start, Daemonize and auto-restart application (Python)

Voor procesbewaking kunt u de volgende commando’s gebruiken:

$ pm2 list # List all processes started with PM2
$ pm2 monit # Display memory and cpu usage of each app
$ pm2 show [app-name] # Show all informations about application

Beheer processen met behulp van de naam van de app of proces id of beheer alle processen samen:

$ pm2 stop <app_name|id|'all'|json_conf>
$ pm2 restart <app_name|id|'all'|json_conf>
$ pm2 delete <app_name|id|'all'|json_conf>

Logfiles zijn te vinden in

$HOME/.pm2/logs #contain all applications logs
-1
-1
-1
2017-04-05 13:47:37 +0000

Als het uw doel is om eenvoudigweg een opdrachtregelapplicatie te starten zonder het terminalvenster rond te houden, dan kunt u proberen om de applicatie na het starten van de terminal met alt-F2 uit te voeren.