it-swarm.com.de

Wie kann ich ein Shell-Skript von einem anderen Shell-Skript aus aufrufen?

Ich habe zwei Shell-Skripte, a.sh und b.sh.

Wie kann ich b.sh aus dem Shell-Skript a.sh aufrufen?

560
Praveen

Es gibt verschiedene Möglichkeiten, dies zu tun:

  1. Machen Sie das andere Skript ausführbar, fügen Sie oben die #!/bin/bash-Zeile und den Pfad der Datei zur Umgebungsvariable $ PATH hinzu. Dann können Sie es als normalen Befehl aufrufen.

  2. Oder rufen Sie es mit dem Befehl source (Alias ​​ist .) wie folgt auf: source /path/to/script;

  3. Oder verwenden Sie den Befehl bash, um ihn auszuführen: /bin/bash /path/to/script;

Die erste und dritte Methode führen das Skript als einen anderen Prozess aus, sodass auf Variablen und Funktionen im anderen Skript nicht zugegriffen werden kann.
Die zweite Methode führt das Skript im Prozess des ersten Skripts aus und zieht Variablen und Funktionen aus dem anderen Skript ein, sodass sie vom aufrufenden Skript verwendet werden können. 

Wenn Sie in der zweiten Methode exit im zweiten Skript verwenden, wird auch das erste Skript beendet. Was bei der ersten und dritten Methode nicht passieren wird.

742

Schau dir das an.

#!/bin/bash
echo "This script is about to run another script."
sh ./script.sh
echo "This script has just run another script."
181
Budha

Es gibt mehrere Möglichkeiten, dies zu tun. Terminal zum Ausführen des Skripts:

#!/bin/bash
SCRIPT_PATH="/path/to/script.sh"

# Here you execute your script
"$SCRIPT_PATH"

# or
. "$SCRIPT_PATH"

# or
source "$SCRIPT_PATH"

# or
bash "$SCRIPT_PATH"

# or
eval '"$SCRIPT_PATH"'

# or
OUTPUT=$("$SCRIPT_PATH")
echo $OUTPUT

# or
OUTPUT=`"$SCRIPT_PATH"`
echo $OUTPUT

# or
("$SCRIPT_PATH")

# or
(exec "$SCRIPT_PATH")

All das ist richtig für den Pfad mit Leerzeichen !!!

75

Die Antwort, nach der ich gesucht habe:

( exec "path/to/script" )

Wie bereits erwähnt, ersetzt exec die Shell, ohne einen neuen Prozess zu erstellen. Allerdings können wir es in eine Subshell setzen, was mit den Klammern geschieht. 

EDIT: Eigentlich ist ( "path/to/script" ) genug.

51
Maxim Chetrusca

Sie können mit /bin/sh ein anderes Skript (über Ihr aktuelles Skript) aufrufen oder ausführen:

 # cat showdate.sh
 #!/bin/bash
 echo "Date is: `date`"

 # cat mainscript.sh
 #!/bin/bash
 echo "You are login as: `whoami`"
 echo "`/bin/sh ./showdate.sh`" # exact path for the script file

Die Ausgabe wäre:

 # ./mainscript.sh
 You are login as: root
 Date is: Thu Oct 17 02:56:36 EDT 2013
14
Ranjithkumar T

Abhängig von . Kurz ... Wenn Sie Variablen in die aktuelle Konsole laden und ausführen möchten, können Sie source myshellfile.sh in Ihrem Code verwenden. Beispiel:

!#/bin/bash
set -x
echo "This is an example of run another INTO this session."
source my_lib_of_variables_and_functions.sh
echo "The function internal_function() is defined into my lib."
returned_value=internal_function()
echo $this_is_an_internal_variable

set +x

Wenn Sie nur eine Datei ausführen möchten und das einzige, was Sie interessiert, das Ergebnis ist, können Sie Folgendes tun:

!#/bin/bash
set -x
./executing_only.sh
sh i_can_execute_this_way_too.sh
bash or_this_way.sh
set +x

Ich hoffe, ich helfe Ihnen ... Danke.

14
Douglas Bonafé

Fügen Sie einfach eine Zeile hinzu, die Sie in ein Terminal eingegeben haben, um das Skript auszuführen!
z.B.:

#!bin/bash
./myscript.sh &

wenn sich das auszuführende Skript nicht im selben Verzeichnis befindet, verwenden Sie einfach den vollständigen Pfad des Skripts.
z.B.:`/home/user/script-directory/./myscript.sh &

9
Anon

Einfache Quelle wird Ihnen helfen.

#!/bin/bash
echo "My Shell_1"
source my_script1.sh
echo "Back in Shell_1"
7
Nitin Jawarkar

Zuerst müssen Sie die Datei angeben, die Sie anrufen:

#!/bin/bash
. includes/included_file.sh

dann rufen Sie Ihre Funktion so auf:

#!/bin/bash
my_called_function
7
Ghazi Triki
pathToShell="/home/praveen/"   
chmod a+x $pathToShell"myShell.sh"
sh $pathToShell"myShell.sh"
4
Abdennour TOUMI
 #!/bin/bash

 # Here you define the absolute path of your script

 scriptPath="/home/user/pathScript/"

 # Name of your script

 scriptName="myscript.sh"

 # Here you execute your script

 $scriptPath/$scriptName

 # Result of script execution

 result=$?
4
Valero

Angenommen, die neue Datei ist "/ home/satya/app/app_specific_env" und der Inhalt der Datei lautet wie folgt

#!bin/bash

export FAV_NUMBER="2211"

Fügen Sie diesen Dateiverweis an die Datei ~/.bashrc an

source /home/satya/app/app_specific_env

Wenn Sie den Computer neu starten oder neu anmelden, versuchen Sie echo $FAV_NUMBER im Terminal. Der Wert wird ausgegeben. 

Für den Fall, dass Sie den Effekt sofort sehen möchten, source ~/.bashrc in der Befehlszeile.

3
Satya Kalluri
chmod a+x /path/to/file-to-be-executed

Das war das einzige, was ich brauchte. Sobald das auszuführende Skript auf diese Weise ausführbar gemacht wurde, benötigen Sie (zumindest in meinem Fall) keine zusätzlichen Operationen wie sh oder ./, während Sie das Skript aufrufen.

Vielen Dank an den Kommentar von @Nathan Lilienthal 

2
Asqan

Die oberste Antwort schlägt vor, die Zeile #!/bin/bash In die erste Zeile des aufgerufenen Sub-Skripts einzufügen. Aber auch wenn Sie den Shebang hinzufügen, ist es viel schneller* So führen Sie ein Skript in einer Sub-Shell aus und erfassen die Ausgabe:

$(source SCRIPT_NAME)

Dies funktioniert, wenn Sie denselben Interpreter weiter ausführen möchten (z. B. von Bash zu einem anderen Bash-Skript) und sicherstellen möchten, dass die Shebang-Zeile des Sub-Skripts nicht ausgeführt wird.

Zum Beispiel:

#!/bin/bash
SUB_SCRIPT=$(mktemp)
echo "#!/bin/bash" > $SUB_SCRIPT
echo 'echo $1' >> $SUB_SCRIPT
chmod +x $SUB_SCRIPT
if [[ $1 == "--source" ]]; then
  for X in $(seq 100); do
    MODE=$(source $SUB_SCRIPT "source on")
  done
else
  for X in $(seq 100); do
    MODE=$($SUB_SCRIPT "source off")
  done
fi
echo $MODE
rm $SUB_SCRIPT

Ausgabe:

~ ❯❯❯ time ./test.sh
source off
./test.sh  0.15s user 0.16s system 87% cpu 0.360 total

~ ❯❯❯ time ./test.sh --source
source on
./test.sh --source  0.05s user 0.06s system 95% cpu 0.114 total

* Wenn beispielsweise Viren- oder Sicherheitstools auf einem Gerät ausgeführt werden, kann es zusätzliche 100 ms dauern, bis ein neuer Prozess ausgeführt wird.

2
cmcginty

Backticks verwenden.

$ ./script-that-consumes-argument.sh `sh script-that-produces-argument.sh`

Rufen Sie dann die Ausgabe des Producer-Skripts als Argument im Konsumentenskript ab.

1
David Cabrera

Es gibt einige Probleme beim Importieren von Funktionen aus anderen Dateien.
Zuerst : Sie müssen diese Datei nicht ausführbar machen. Besser nicht so ! Einfach hinzufügen 

. file

alle Funktionen importieren. Und alle werden so sein, als wären sie in Ihrer Datei definiert.
Sekunde : Möglicherweise definieren Sie die Funktion mit demselben Namen. Es wird überschrieben. Es ist schlecht. Sie können so erklären

declare -f new_function_name=old_function_name 

und erst danach importieren Sie . Sie können also die alte Funktion mit dem neuen Namen aufrufen.
Drittens : Sie können nur die vollständige Liste der in der Datei definierten Funktionen importieren. Wenn Sie Ihre Funktionen jedoch nach dem Deaktivieren neu schreiben, gehen sie verloren. Wenn Sie jedoch wie oben beschrieben einen Verweis darauf setzen, können Sie die Wiederherstellung nach dem gleichen Namen mit demselben Namen wiederherstellen.
Schließlich Im allgemeinen Verfahren ist der Import gefährlich und nicht so einfach. Achtung! Sie können ein Skript schreiben, um dies einfacher und sicherer zu machen. Wenn Sie nur einen Teil der Funktionen (nicht alle) verwenden, teilen Sie sie besser in verschiedene Dateien auf. Leider ist diese Technik in bash nicht gut gemacht. In Python zum Beispiel und in einigen anderen Skriptsprachen ist das einfach und sicher. Möglicher teilweiser Import nur benötigter Funktionen mit eigenen Namen. Wir alle möchten, dass in den nächsten Bush-Versionen die gleiche Funktionalität ausgeführt wird. Aber jetzt müssen wir viele zusätzliche Kabeljau schreiben, um das zu tun, was Sie wollen. 

0
Anatoly