Ich habe zwei Shell-Skripte, a.sh
und b.sh
.
Wie kann ich b.sh
aus dem Shell-Skript a.sh
aufrufen?
Es gibt verschiedene Möglichkeiten, dies zu tun:
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.
Oder rufen Sie es mit dem Befehl source
(Alias ist .
) wie folgt auf: source /path/to/script
;
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.
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."
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 !!!
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.
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
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.
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 &
Einfache Quelle wird Ihnen helfen.
#!/bin/bash
echo "My Shell_1"
source my_script1.sh
echo "Back in Shell_1"
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
pathToShell="/home/praveen/"
chmod a+x $pathToShell"myShell.sh"
sh $pathToShell"myShell.sh"
#!/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=$?
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.
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
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.
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.
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.