Tout moyen de quitter le script bash, mais ne pas quitter le terminal

Lorsque j'utilise la commande exit dans un script shell, le script terminera le terminal (l'invite). Existe-t-il un moyen de terminer un script puis de rester dans le terminal?

Mon script run.sh est censé s'exécuter en étant directement sourcé, ou provenant d'un autre script.

Modifier: Pour être plus précis, il y a deux scripts run2.sh comme

...
. run.sh
echo "place A"
...

Et run.sh, comme

...
exit
...

Quand je le lance par . run2.sh, et si il a frappé exit codeline dans run.sh, je veux arrêter de le terminal et rester là. Mais en utilisant exit, tout le terminal est fermé.

PS: j'ai essayé d'utiliser return, mais echo codeline sera toujours exécuté....

138
demandé sur Richard 2012-03-10 00:38:24

10 réponses

Le" problème " est vraiment que vous sourcez et n'exécutez pas le script. Lorsque vous sourcez un fichier, son contenu sera exécuté dans le shell actuel, au lieu de générer un sous-shell. Donc, tout, y compris la sortie, affectera le shell actuel.

Au lieu d'utiliser exit, Vous voudrez utiliser return.

197
répondu Dominik Honnef 2012-03-09 20:44:19

Oui, vous pouvez utiliser return au lieu de exit. Son but principal est de retourner à partir d'une fonction shell, mais si vous l'utilisez dans un script source-d, il retourne à partir de ce script.

, Comme §4.1 "Bourne Shell objets internes" de la Bash Manuel de Référence il met:

     return [n]

Provoque la sortie d'une fonction shell avec la valeur de retour n . Si N n'est pas fourni, la valeur de retour est l'état de sortie du dernière commande exécutée dans le fonction. Cela peut également être utilisé pour terminer l'exécution d'un script en cours d'exécution avec . (ou source) intégré, renvoyant soit n ou l'état de sortie de la dernière commande exécutée dans le script en tant que sortie statut du script. Toute commande associée au trap RETURN est exécutée avant l'exécution reprend après la fonction ou le script. L'état de retour est différent de zéro si return est utilisé en dehors d'une fonction et pas pendant l'exécution d'un script par . ou source.

32
répondu ruakh 2012-03-09 20:43:18

Au lieu d'exécuter le code en utilisant . run2.sh Vous pouvez exécuter le script en utilisant sh run2.sh ou bash run2.sh
Une nouvelle instance sera ouverte pour exécuter le script puis elle sera fermée à la fin du script en laissant l'autre shell ouvert. `

10
répondu Viorel Mirea 2015-11-04 19:43:41

C'est comme si vous mettiez une fonction d'exécution dans votre script run2.sh. Vous utilisez le code de sortie à l'intérieur de run while source your run2.sh fichier dans le tty bash. Si la fonction give the run a le pouvoir de quitter votre script et de run2.sh son pouvoir de quitter le terminator. Ensuite, la fonction run a le pouvoir de quitter votre teminator.

    #! /bin/sh
    # use . run2.sh

    run()
    {
        echo "this is run"
        #return 0
        exit 0
    }

    echo "this is begin"
    run
    echo "this is end"

De toute façon, j'approuve avec Kaz c'est un problème de conception.

2
répondu Umae 2012-03-10 08:18:21

Je pense que cela se produit parce que vous l'exécutez en mode source avec le point

. myscript.sh

Vous devriez l'exécuter dans un sous-shell:

/full/path/to/script/myscript.sh

'source' http://ss64.com/bash/source.html

2
répondu JBoy 2013-09-19 11:13:50

Il est correct que les scripts sourcés par rapport aux scripts exécutés utilisent return par rapport à exit pour garder la même session ouverte, comme d'autres l'ont noté.

Voici une astuce connexe, si vous voulez un script qui devrait garder la session ouverte, qu'elle soit sourcée ou non.

L'exemple suivant peut être exécuté directement comme foo.sh ou comme source . foo.sh/source foo.sh. De toute façon, il gardera la session ouverte après "sortie". La chaîne $@ est passée de sorte que la fonction ait accès à l'extérieur script arguments.

#!/bin/sh
foo(){
    read -p "Would you like to XYZ? (Y/N): " response;
    [ $response != 'y' ] && return 1;
    echo "XYZ complete (args $@).";
    return 0;
    echo "This line will never execute.";
}
foo "$@";

Résultat Terminal:

$ foo.sh
$ Aimeriez-vous XYZ? (O / N): n
$ . foo.sh
$ Aimeriez-vous XYZ? (O / N): n
$ |
(la fenêtre du terminal reste ouverte et accepte une entrée supplémentaire)

Cela peut être utile pour tester rapidement les modifications de script dans un seul terminal tout en gardant un tas de code de rebut sous le main exit/return pendant que tu travailles. Cela pourrait également rendre le code plus portable dans un sens (si vous avez des tonnes de scripts qui peuvent ou non être appelés de différentes manières), bien qu'il soit beaucoup moins maladroit d'utiliser simplement return et exit le cas échéant.

1
répondu Beejor 2017-11-06 22:56:37

Si votre émulateur de terminal n'a pas -hold vous pouvez désinfecter un script source et maintenir le terminal avec:

#!/bin/sh
sed "s/exit/return/g" script >/tmp/script
. /tmp/script
read

Sinon, vous pouvez utiliser $TERM -hold -e script

0
répondu technosaurus 2012-03-10 22:15:13

Assurez-vous également de retourner avec la valeur de retour attendue. Sinon, si vous utilisez exit lorsque vous rencontrerez une sortie, elle quittera votre shell de base car la source ne crée pas d'autre processus (instance).

0
répondu coder23 2015-04-02 21:46:18

Pour écrire un script qui est à l'épreuve des balles pour être exécuté en tant que script shell ou en tant que Fichier rc, le script peut vérifier et comparer $0 et $BASH_SOURCE et déterminer si exit peut être utilisé en toute sécurité.

Voici un extrait de code court pour cela

[ "X$(basename $0)" = "X$(basename $BASH_SOURCE)" ] && \
    echo "***** executing $name_src as a shell script *****" || \
    echo "..... sourcing $name_src ....."
0
répondu Tzunghsing David Wong 2018-09-21 02:04:30

1) exit 0 sortira du script s'il réussit.

2) exit 1 sortira du script s'il s'agit d'un échec.

Vous pouvez essayer ces deux ci-dessus en fonction de votre req.

-2
répondu Teja 2012-03-09 20:41:55