Lorsque j'utilise la commande exit
dans un script Shell, le script met fin au terminal (l'invite). Existe-t-il un moyen de terminer un script et de rester dans le terminal?
Mon script run.sh
est censé s'exécuter directement ou directement à partir d'un autre script.
EDIT: 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 s'il touche le code exit
dans run.sh
, je veux qu'il s'arrête au terminal et y reste Mais en utilisant exit
, tout le terminal est fermé.
PS: J'ai essayé d'utiliser return
, mais echo
codeline sera toujours exécuté ....
Le "problème" est vraiment que vous effectuez le sourcing et n'exécutez pas le script. Lorsque vous sourcez un fichier, son contenu sera exécuté dans le shell actuel au lieu de créer un sous-shell. Donc, tout, y compris la sortie, affectera le Shell actuel.
Au lieu d'utiliser exit
, vous voudrez utiliser return
.
Oui; vous pouvez utiliser return
au lieu de exit
. Son objectif principal est de revenir 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 Builtins" du manuel de référence Bash le dit:
return [n]
Permet à une fonction Shell de quitter avec la valeur de retour n. Si n n'est pas fourni, la valeur de retour est l'état de sortie du fichier dernière commande exécutée dans la fonction. Ceci peut également être utilisé pour terminer l'exécution d'un script en cours d'exécution avec le
.
(ousource
) intégré, retournant soit n ou l'état de sortie de la dernière commande exécutée dans le script en tant qu'exit statut du script. Toute commande associée à l’interruptionRETURN
est exécutée avant que l'exécution reprenne après la fonction ou le script. Le statut de retour est différent de zéro sireturn
est utilisé en dehors d'une fonction et pas pendant l'exécution d'un script par.
ousource
.
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 il sera fermé à la fin du script, laissant l'autre shell ouvert . `
C’est comme si vous mettiez une fonction d’exécution dans votre script run2.sh . Vous utilisiez le code de sortie dans exécution pendant que le fichier run2.sh est utilisé dans le bash tty . votre script et donnez à run2.sh .__ son pouvoir de sortir du terminateur . 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"
Quoi qu'il en soit, j'approuve avec Kaz que c'est un problème de conception.
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
J'ai eu le même problème et d'après les réponses ci-dessus et d'après ce que j'ai compris, ce qui a finalement fonctionné pour moi a été
#!/bin/bash
utilise bash pour exécuter le scriptJ'ai des scripts avec les deux types de Shebang. Pour cette raison, en utilisant sh ou. n'était pas fiable, car cela conduisait à une erreur d'exécution (comme lorsque le script ne s'exécute pas complètement)
La réponse était donc
./myscript.sh
J'espère que cela aide quelqu'un avec des exigences/circonstances similaires
Il est exact que les scripts sourcés vs exécutés utilisent return
contre exit
pour garder la même session ouverte, comme d'autres l'ont déjà noté.
Voici un conseil connexe si vous souhaitez un script qui maintienne la session ouverte, qu’il soit ou non source.
L'exemple suivant peut être exécuté directement comme foo.sh
ou créé comme . foo.sh
/source foo.sh
. Dans tous les cas, la session reste ouverte après la "fermeture". La chaîne $@
est transmise de sorte que la fonction ait accès aux arguments du script externe.
#!/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 final:
$ foo.sh
$ Voulez-vous XYZ? (O/N): n
$. foo.sh
$ Voulez-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 conservant un tas de code de rebut sous la variable exit
/return
pendant que vous travaillez. Cela pourrait également rendre le code plus portable dans un sens (si vous avez des tonnes de scripts qui peuvent être appelés de différentes manières), bien qu'il soit beaucoup moins pratique d'utiliser simplement return
et exit
si nécessaire.
En fait, je pense que vous pourriez être dérouté par la façon dont vous "exécutez un script".
Si vous utilisez sh
pour exécuter un script, par exemple, sh ./run2.sh
, même si le script incorporé se termine par exit
, votre fenêtre de terminal restera toujours affichée.
Cependant, si vous utilisez .
ou source
, la fenêtre de votre terminal se ferme/se ferme également à la fin de l'indice.
pour plus de détails, veuillez vous référer à Quelle est la différence entre sh
et source
?
Pour écrire un script à l'épreuve des balles à exécuter en tant que script Shell ou créé sous forme de 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 l'extrait de code court pour cette
[ "X$(basename $0)" = "X$(basename $BASH_SOURCE)" ] && \
echo "***** executing $name_src as a Shell script *****" || \
echo "..... sourcing $name_src ....."
Vous pouvez ajouter une commande de sortie supplémentaire après la commande de retour afin qu'elle fonctionne à la fois pour l'exécution du script à partir de la ligne de commande et la recherche de sources à partir du terminal.
Exemple de code de sortie dans le script:
if [ $# -lt 2 ]; then
echo "Needs at least two arguments"
return 1 2>/dev/null
exit 1
fi
La ligne avec la commande exit
ne sera pas appelée lorsque vous sourcez le script après la commande return
.
Lorsque vous exécutez le script, la commande return
génère une erreur. Donc, nous supprimons le message d'erreur en le transférant à /dev/null
.
Assurez-vous également de renvoyer avec la valeur de retour attendue. Sinon, si vous utilisez exit lorsque vous rencontrerez une sortie, il sortira de votre shell de base car la source ne crée pas un autre processus (instance).
si votre émulateur de terminal n'a pas -hold
, vous pouvez assainir un script source et conserver le terminal avec:
#!/bin/sh
sed "s/exit/return/g" script >/tmp/script
. /tmp/script
read
sinon vous pouvez utiliser $TERM -hold -e script