Diese Frage ist zwar nützlich, wird aber nicht gut gestellt. Ruby hat viele Möglichkeiten, Sub-Shells aufzurufen, die gut dokumentiert und leicht zu finden sind, indem Sie die Kernel- und Open3- Dokumentation lesen und hier auf SO suchen.
der Blechmann
1
Leider ist dieses Thema ziemlich komplex. Open3( docs ) ist die beste Wahl für die meisten Situationen, IMO, aber in älteren Versionen von Ruby werden modifizierte PATH( bugs.ruby-lang.org/issues/8004 ) und je nachdem, wie Sie Argumente übergeben ( insbesondere ), nicht berücksichtigt Wenn Sie opts-Hash mit Nicht-Schlüsselwörtern verwenden, kann dies zu Problemen führen. Wenn Sie jedoch auf diese Situationen stoßen, tun Sie etwas ziemlich Fortgeschrittenes und können herausfinden, was zu tun ist, indem Sie die Implementierung von lesen Open3.
Joshua Cheek
3
Ich bin überrascht, dass niemand etwas erwähnt hat Shellwords.escape( doc ). Sie möchten keine Benutzereingaben direkt in Shell-Befehle einfügen - entkommen Sie zuerst! Siehe auch Befehlsinjektion .
Kelvin
Antworten:
1319
Diese Erklärung basiert auf einem kommentierten Ruby-Skript eines Freundes von mir. Wenn Sie das Skript verbessern möchten, können Sie es unter dem Link aktualisieren.
Beachten Sie zunächst, dass , wenn Ruby eine Shell ruft, ruft die Regel /bin/sh, nicht Bash. Einige Bash-Syntax wird nicht /bin/shauf allen Systemen unterstützt.
Hier sind Möglichkeiten, ein Shell-Skript auszuführen:
cmd ="echo 'hi'"# Sample string that can be used
Kernel#` , allgemein als Backticks bezeichnet - `cmd`
Dies ist wie bei vielen anderen Sprachen, einschließlich Bash, PHP und Perl.
Gibt das Ergebnis (dh die Standardausgabe) des Shell-Befehls zurück.
Dem xZeichen folgt ein Trennzeichen, das ein beliebiges Zeichen sein kann. Wenn das Trennzeichen eines der Zeichen (ist [, {oder <, besteht das Literal aus den Zeichen bis zum übereinstimmenden schließenden Trennzeichen unter Berücksichtigung verschachtelter Trennzeichenpaare. Bei allen anderen Trennzeichen umfasst das Literal die Zeichen bis zum nächsten Auftreten des Trennzeichens. String-Interpolation #{ ... }ist erlaubt.
Gibt das Ergebnis (dh die Standardausgabe) des Shell-Befehls zurück, genau wie die Backticks.
exec("echo 'hi'")exec( cmd )# Note: this will never be reached because of the line above
Hier einige zusätzliche Beratung:
$?, das ist die gleiche wie $CHILD_STATUS, greift auf den Status des letzten System ausgeführten Befehls , wenn Sie die Backticks verwenden, system()oder %x{}. Sie können dann auf die Eigenschaften exitstatusund zugreifen pid:
Ich muss die Ausgaben meiner ausführbaren Datei auf dem Produktionsserver protokollieren, habe aber keine Möglichkeit gefunden. Ich habe Puts #{cmd}und logger.info ( #{cmd}) verwendet. Gibt es eine Möglichkeit, ihre Ausgaben in der Produktion zu protokollieren?
Der Vollständigkeit halber (wie ich zuerst dachte, wäre dies auch ein Ruby-Befehl): Rake hat sh, was "Systembefehl cmdausführen " ausführt . Wenn mehrere Argumente angegeben werden, wird der Befehl nicht mit der Shell ausgeführt (gleiche Semantik wie Kernel :: exec und Kernel :: system) ".
Sschuberth
40
Backticks erfassen STDERR standardmäßig nicht. Fügen Sie `2> & 1` zum Befehl hinzu, wenn Sie erfassen möchten
Andrei Botalov
14
Ich denke, diese Antwort würde sich leicht verbessern, wenn sie besagt, dass Backticks und% x die "Ausgabe" und nicht das "Ergebnis" des angegebenen Befehls zurückgeben. Letzteres könnte mit dem Exit-Status verwechselt werden. Oder bin das nur ich?
Wow haha. Sehr nützlich, obwohl die Tatsache, dass dies existieren muss, unglücklich ist
Josh Bodah
Als Randnotiz finde ich die spawn () -Methode an vielen verschiedenen Stellen (z. B. Kernelund Processam vielseitigsten). Sie ist mehr oder weniger dieselbe PTY.spawn(), aber allgemeiner.
Smar
160
Die Art und Weise, wie ich das mache, ist die Verwendung des %xLiteral, was es einfach (und lesbar!) Macht, Anführungszeichen in einem Befehl zu verwenden, wie folgt:
directorylist =%x[find .-name '*test.rb'| sort]
In diesem Fall wird die Dateiliste mit allen Testdateien im aktuellen Verzeichnis gefüllt, die Sie wie erwartet verarbeiten können:
directorylist.each do|filename|
filename.chomp!# work with fileend
das obige funktioniert bei mir nicht. `` <main> ': undefinierte Methode each' for :String (NoMethodError) Wie hat es bei Ihnen funktioniert? Ich verwende ruby -v ruby 1.9.3p484 (2013-11-22 revision 43786) [i686-linux]Sind Sie sicher, dass ein Array vom Befehl zurückgegeben wird, damit die Schleife tatsächlich funktioniert?
Nasser
% x [cmd] .split ("\ n") gibt jedoch eine Liste zurück :)
Gibt es eine Dokumentation zur Durchführung von Spezifikations- und Komponententests mit Open3 oder anderen Open in der Ruby std-lib? Nach meinem derzeitigen Verständnis ist es schwierig, Shell-Outs zu testen.
FilBot3
29
Einige Dinge, über die Sie nachdenken sollten, wenn Sie zwischen diesen Mechanismen wählen, sind:
Willst du nur stdout oder brauchst du auch stderr? Oder sogar getrennt?
Wie groß ist Ihre Leistung? Möchten Sie das gesamte Ergebnis im Speicher behalten?
Möchten Sie einen Teil Ihrer Ausgabe lesen, während der Unterprozess noch ausgeführt wird?
Benötigen Sie Ergebniscodes?
Benötigen Sie ein Ruby-Objekt, das den Prozess darstellt und das Sie bei Bedarf beenden können?
Sie können alles von einfachen Backticks benötigen ( ``), system()und IO.popenzu ausgewachsenen Kernel.fork/ Kernel.execmit IO.pipeund IO.select.
Möglicherweise möchten Sie auch Timeouts in den Mix einfügen, wenn die Ausführung eines Unterprozesses zu lange dauert.
Wenn Sie Bash wirklich brauchen, lesen Sie den Hinweis in der "besten" Antwort.
Beachten Sie zunächst, dass , wenn Ruby eine Shell ruft, ruft die Regel /bin/sh, nicht Bash. Einige Bash-Syntax wird nicht /bin/shauf allen Systemen unterstützt.
Wenn Sie Bash verwenden müssen, fügen Sie es bash -c "your Bash-only command"in die gewünschte Aufrufmethode ein:
Sie können auch die Backtick-Operatoren (`) verwenden, ähnlich wie bei Perl:
directoryListing =`ls /`
puts directoryListing # prints the contents of the root directory
Praktisch, wenn Sie etwas Einfaches brauchen.
Welche Methode Sie verwenden möchten, hängt genau davon ab, was Sie erreichen möchten. Weitere Informationen zu den verschiedenen Methoden finden Sie in den Dokumenten.
Wenn der Kernel#systemBefehl verwendet wird, wird zurückgegeben, truewenn er erfolgreich ist, falsewenn er nicht erfolgreich ist, und wird zurückgegeben, nilwenn die Befehlsausführung fehlschlägt:
Mit den Antworten hier und in Mihais Antwort verknüpft, habe ich eine Funktion zusammengestellt, die diese Anforderungen erfüllt:
Erfasst STDOUT und STDERR ordentlich, damit sie nicht "auslaufen", wenn mein Skript von der Konsole ausgeführt wird.
Ermöglicht die Übergabe von Argumenten an die Shell als Array, sodass Sie sich keine Gedanken über das Escape machen müssen.
Erfasst den Beendigungsstatus des Befehls, sodass klar ist, wann ein Fehler aufgetreten ist.
Als Bonus gibt dieser auch STDOUT zurück, wenn der Shell-Befehl erfolgreich beendet wird (0) und STDOUT aktiviert. Auf diese Weise unterscheidet es sich von system, was truein solchen Fällen einfach zurückkehrt .
Code folgt. Die spezifische Funktion ist system_quietly:
require'open3'classShellError<StandardError;end#actual function:def system_quietly(*cmd)
exit_status=nil
err=nilout=nilOpen3.popen3(*cmd)do|stdin, stdout, stderr, wait_thread|
err = stderr.gets(nil)out= stdout.gets(nil)[stdin, stdout, stderr].each{|stream| stream.send('close')}
exit_status = wait_thread.valueendif exit_status.to_i >0
err = err.chomp if err
raiseShellError, err
elsifoutreturnout.chomp
elsereturntrueendend#calling it:begin
puts system_quietly('which','ruby')rescueShellError
abort "Looks like you don't have the `ruby` command. Odd."end#output: => "/Users/me/.rvm/rubies/ruby-1.9.2-p136/bin/ruby"
Vergessen Sie nicht den spawnBefehl zum Erstellen eines Hintergrundprozesses zum Ausführen des angegebenen Befehls. Sie können sogar mit der ProcessKlasse und der zurückgegebenen Klasse auf den Abschluss warten pid:
Kernel.spawn()scheint weitaus vielseitiger zu sein als alle anderen Optionen.
Kashyap
6
Wenn Sie einen komplexeren Fall als den allgemeinen haben, der nicht behandelt werden kann ``, überprüfen Sie ihn Kernel.spawn(). Dies scheint die allgemeinste / umfassendste Version zu sein, die von Stock Ruby zur Ausführung externer Befehle bereitgestellt wird.
Sie können es verwenden, um:
Prozessgruppen erstellen (Windows).
Fehler in Dateien / untereinander umleiten.
setze env vars, umask.
Ändern Sie das Verzeichnis, bevor Sie einen Befehl ausführen.
Ressourcenlimits für CPU / Daten / etc. festlegen.
Machen Sie alles, was mit anderen Optionen in anderen Antworten möglich ist, aber mit mehr Code.
env: hash
name => val :set the environment variable
name =>nil: unset the environment variable
command...:
commandline : command line string which is passed to the standard shell
cmdname, arg1,...: command name and one or more arguments (no shell)[cmdname, argv0], arg1,...: command name, argv[0]and zero or more arguments (no shell)
options: hash
clearing environment variables::unsetenv_others =>true: clear environment variables except specified by env
:unsetenv_others =>false: dont clear (default)
process group::pgroup =>trueor0: make a new process group:pgroup => pgid :join to specified process group:pgroup =>nil: dont change the process group(default)
create new process group:Windows only
:new_pgroup =>true: the new process is the root process of a new process group:new_pgroup =>false: dont create a new process group(default)
resource limit: resourcename is core, cpu, data, etc.SeeProcess.setrlimit.:rlimit_resourcename => limit
:rlimit_resourcename =>[cur_limit, max_limit]
current directory::chdir => str
umask::umask =>int
redirection:
key:
FD : single file descriptor in child process
[FD, FD,...]: multiple file descriptor in child process
value:
FD : redirect to the file descriptor in parent process
string: redirect to file with open(string,"r"or"w")[string]: redirect to file with open(string,File::RDONLY)[string, open_mode]: redirect to file with open(string, open_mode,0644)[string, open_mode, perm]: redirect to file with open(string, open_mode, perm)[:child, FD]: redirect to the redirected file descriptor
:close : close the file descriptor in child process
FD is one of follows
:in: the file descriptor 0 which is the standard input
:out: the file descriptor 1 which is the standard output
:err : the file descriptor 2 which is the standard error
integer : the file descriptor of specified the integer
io : the file descriptor specified as io.fileno
file descriptor inheritance: close non-redirected non-standard fds (3,4,5,...)ornot:close_others =>false: inherit fds (defaultfor system andexec):close_others =>true: dont inherit (defaultfor spawn and IO.popen)
require'open3'
a="attrib"Open3.popen3(a)do|stdin, stdout, stderr|
puts stdout.read
end
Ich habe festgestellt, dass diese Methode zwar nicht so einprägsam ist wie
system("thecommand")
oder
`thecommand`
In Backticks ist eine gute Sache bei dieser Methode im Vergleich zu anderen Methoden, dass Backticks mir putsden Befehl, den ich ausführe / speichere, nicht in einer Variablen zulassen / speichern und system("thecommand")mir nicht die Ausgabe zu ermöglichen scheinen Mit dieser Methode kann ich beides tun und unabhängig voneinander auf stdin, stdout und stderr zugreifen.
Dies ist keine wirkliche Antwort, aber vielleicht findet es jemand nützlich:
Wenn Sie die TK-Benutzeroberfläche unter Windows verwenden und Shell-Befehle von rubyw aus aufrufen müssen, wird immer weniger als eine Sekunde lang ein nerviges CMD-Fenster angezeigt.
Um dies zu vermeiden, können Sie Folgendes verwenden:
Hier ist eine coole Version, die ich in einem Ruby-Skript unter OS X verwende (damit ich ein Skript starten und ein Update erhalten kann, auch nachdem ich vom Fenster weggeschaltet habe):
cmd =%Q|osascript -e 'display notification "Server was reset" with title "Posted Update"'|
system ( cmd )
Open3
( docs ) ist die beste Wahl für die meisten Situationen, IMO, aber in älteren Versionen von Ruby werden modifiziertePATH
( bugs.ruby-lang.org/issues/8004 ) und je nachdem, wie Sie Argumente übergeben ( insbesondere ), nicht berücksichtigt Wenn Sie opts-Hash mit Nicht-Schlüsselwörtern verwenden, kann dies zu Problemen führen. Wenn Sie jedoch auf diese Situationen stoßen, tun Sie etwas ziemlich Fortgeschrittenes und können herausfinden, was zu tun ist, indem Sie die Implementierung von lesenOpen3
.Shellwords.escape
( doc ). Sie möchten keine Benutzereingaben direkt in Shell-Befehle einfügen - entkommen Sie zuerst! Siehe auch Befehlsinjektion .Antworten:
Diese Erklärung basiert auf einem kommentierten Ruby-Skript eines Freundes von mir. Wenn Sie das Skript verbessern möchten, können Sie es unter dem Link aktualisieren.
Beachten Sie zunächst, dass , wenn Ruby eine Shell ruft, ruft die Regel
/bin/sh
, nicht Bash. Einige Bash-Syntax wird nicht/bin/sh
auf allen Systemen unterstützt.Hier sind Möglichkeiten, ein Shell-Skript auszuführen:
Kernel#`
, allgemein als Backticks bezeichnet -`cmd`
Dies ist wie bei vielen anderen Sprachen, einschließlich Bash, PHP und Perl.
Gibt das Ergebnis (dh die Standardausgabe) des Shell-Befehls zurück.
Dokumente: http://ruby-doc.org/core/Kernel.html#method-i-60
Eingebaute Syntax,
%x( cmd )
Dem
x
Zeichen folgt ein Trennzeichen, das ein beliebiges Zeichen sein kann. Wenn das Trennzeichen eines der Zeichen(
ist[
,{
oder<
, besteht das Literal aus den Zeichen bis zum übereinstimmenden schließenden Trennzeichen unter Berücksichtigung verschachtelter Trennzeichenpaare. Bei allen anderen Trennzeichen umfasst das Literal die Zeichen bis zum nächsten Auftreten des Trennzeichens. String-Interpolation#{ ... }
ist erlaubt.Gibt das Ergebnis (dh die Standardausgabe) des Shell-Befehls zurück, genau wie die Backticks.
Dokumente: https://docs.ruby-lang.org/en/master/syntax/literals_rdoc.html#label-Percent+Strings
Kernel#system
Führt den angegebenen Befehl in einer Subshell aus.
Gibt zurück,
true
wenn der Befehl gefunden und erfolgreich ausgeführt wurde,false
andernfalls.Dokumente: http://ruby-doc.org/core/Kernel.html#method-i-system
Kernel#exec
Ersetzt den aktuellen Prozess durch Ausführen des angegebenen externen Befehls.
Gibt keine zurück, der aktuelle Prozess wird ersetzt und wird nie fortgesetzt.
Dokumente: http://ruby-doc.org/core/Kernel.html#method-i-exec
Hier einige zusätzliche Beratung:
$?
, das ist die gleiche wie$CHILD_STATUS
, greift auf den Status des letzten System ausgeführten Befehls , wenn Sie die Backticks verwenden,system()
oder%x{}
. Sie können dann auf die Eigenschaftenexitstatus
und zugreifenpid
:Weitere Informationen finden Sie unter:
quelle
#{cmd}
und logger.info (#{cmd}
) verwendet. Gibt es eine Möglichkeit, ihre Ausgaben in der Produktion zu protokollieren?cmd
ausführen " ausführt . Wenn mehrere Argumente angegeben werden, wird der Befehl nicht mit der Shell ausgeführt (gleiche Semantik wie Kernel :: exec und Kernel :: system) ".Hier ist ein Flussdiagramm, das auf " Wann soll jede Methode zum Starten eines Unterprozesses in Ruby verwendet werden " basiert . Siehe auch " Trick eine Anwendung in den Gedanken, dass ihr Standard ein Terminal ist, keine Pipe ".
quelle
Kernel
undProcess
am vielseitigsten). Sie ist mehr oder weniger dieselbePTY.spawn()
, aber allgemeiner.Die Art und Weise, wie ich das mache, ist die Verwendung des
%x
Literal, was es einfach (und lesbar!) Macht, Anführungszeichen in einem Befehl zu verwenden, wie folgt:In diesem Fall wird die Dateiliste mit allen Testdateien im aktuellen Verzeichnis gefüllt, die Sie wie erwartet verarbeiten können:
quelle
%x[ cmd ]
Ihnen ein Array zurück?each' for :String (NoMethodError)
Wie hat es bei Ihnen funktioniert? Ich verwenderuby -v ruby 1.9.3p484 (2013-11-22 revision 43786) [i686-linux]
Sind Sie sicher, dass ein Array vom Befehl zurückgegeben wird, damit die Schleife tatsächlich funktioniert?Hier ist meiner Meinung nach der beste Artikel zum Ausführen von Shell-Skripten in Ruby: " 6 Möglichkeiten zum Ausführen von Shell-Befehlen in Ruby ".
Wenn Sie nur die Ausgabe benötigen, verwenden Sie Backticks.
Ich brauchte fortgeschrittenere Sachen wie STDOUT und STDERR, also habe ich das Open4-Juwel verwendet. Sie haben dort alle Methoden erklärt.
quelle
%x
.spawn
Methode zu implementieren , als ich diese fand.Mein Favorit ist Open3
quelle
stdout, stderr, status = Open3.capture3('nroff -man', :stdin_data => stdin)
Einige Dinge, über die Sie nachdenken sollten, wenn Sie zwischen diesen Mechanismen wählen, sind:
Sie können alles von einfachen Backticks benötigen ( ``),
system()
undIO.popen
zu ausgewachsenenKernel.fork
/Kernel.exec
mitIO.pipe
undIO.select
.Möglicherweise möchten Sie auch Timeouts in den Mix einfügen, wenn die Ausführung eines Unterprozesses zu lange dauert.
Leider kommt es sehr darauf an .
quelle
Noch eine Option:
Wenn du:
Sie können die Shell-Umleitung verwenden:
Die
2>&1
Syntax funktioniert seit den Anfängen von MS-DOS unter Linux , Mac und Windows .quelle
Ich bin definitiv kein Ruby-Experte, aber ich werde es versuchen:
Sie sollten auch in der Lage sein, Dinge zu tun wie:
quelle
Die obigen Antworten sind bereits ziemlich gut, aber ich möchte wirklich den folgenden zusammenfassenden Artikel teilen: " 6 Möglichkeiten, Shell-Befehle in Ruby auszuführen "
Grundsätzlich sagt es uns:
Kernel#exec
::system
und$?
:Backticks (`):
IO#popen
::Open3#popen3
- stdlib:Open4#popen4
-- ein Edelstein:quelle
Wenn Sie Bash wirklich brauchen, lesen Sie den Hinweis in der "besten" Antwort.
Wenn Sie Bash verwenden müssen, fügen Sie es
bash -c "your Bash-only command"
in die gewünschte Aufrufmethode ein:Zu testen:
Oder wenn Sie eine vorhandene Skriptdatei wie ausführen
Ruby sollte den Schebang ehren, aber du könntest ihn immer gebrauchen
Um sicherzugehen, dass das
/bin/sh
Laufen zwar einen leichten Overhead verursacht/bin/bash
, werden Sie es wahrscheinlich nicht bemerken.quelle
Sie können auch die Backtick-Operatoren (`) verwenden, ähnlich wie bei Perl:
Praktisch, wenn Sie etwas Einfaches brauchen.
Welche Methode Sie verwenden möchten, hängt genau davon ab, was Sie erreichen möchten. Weitere Informationen zu den verschiedenen Methoden finden Sie in den Dokumenten.
quelle
Wir können es auf verschiedene Arten erreichen.
Verwenden Sie
Kernel#exec
nichts, nachdem dieser Befehl ausgeführt wurde:Verwenden von
backticks or %x
Wenn der
Kernel#system
Befehl verwendet wird, wird zurückgegeben,true
wenn er erfolgreich ist,false
wenn er nicht erfolgreich ist, und wird zurückgegeben,nil
wenn die Befehlsausführung fehlschlägt:quelle
Der einfachste Weg ist zum Beispiel:
quelle
Mit den Antworten hier und in Mihais Antwort verknüpft, habe ich eine Funktion zusammengestellt, die diese Anforderungen erfüllt:
Als Bonus gibt dieser auch STDOUT zurück, wenn der Shell-Befehl erfolgreich beendet wird (0) und STDOUT aktiviert. Auf diese Weise unterscheidet es sich von
system
, wastrue
in solchen Fällen einfach zurückkehrt .Code folgt. Die spezifische Funktion ist
system_quietly
:quelle
Vergessen Sie nicht den
spawn
Befehl zum Erstellen eines Hintergrundprozesses zum Ausführen des angegebenen Befehls. Sie können sogar mit derProcess
Klasse und der zurückgegebenen Klasse auf den Abschluss wartenpid
:Das Dokument sagt: Diese Methode ähnelt,
#system
wartet jedoch nicht auf den Abschluss des Befehls.quelle
Kernel.spawn()
scheint weitaus vielseitiger zu sein als alle anderen Optionen.Wenn Sie einen komplexeren Fall als den allgemeinen haben, der nicht behandelt werden kann
``
, überprüfen Sie ihnKernel.spawn()
. Dies scheint die allgemeinste / umfassendste Version zu sein, die von Stock Ruby zur Ausführung externer Befehle bereitgestellt wird.Sie können es verwenden, um:
Die Ruby-Dokumentation enthält genügend Beispiele:
quelle
Die Methode backticks (`) ist die einfachste Methode, um Shell-Befehle von Ruby aus aufzurufen. Es gibt das Ergebnis des Shell-Befehls zurück:
quelle
Gegeben ein Befehl wie
attrib
:Ich habe festgestellt, dass diese Methode zwar nicht so einprägsam ist wie
oder
In Backticks ist eine gute Sache bei dieser Methode im Vergleich zu anderen Methoden, dass Backticks mir
puts
den Befehl, den ich ausführe / speichere, nicht in einer Variablen zulassen / speichern undsystem("thecommand")
mir nicht die Ausgabe zu ermöglichen scheinen Mit dieser Methode kann ich beides tun und unabhängig voneinander auf stdin, stdout und stderr zugreifen.Siehe " Ausführen von Befehlen in Ruby " und Rubys Open3-Dokumentation .
quelle
Dies ist keine wirkliche Antwort, aber vielleicht findet es jemand nützlich:
Wenn Sie die TK-Benutzeroberfläche unter Windows verwenden und Shell-Befehle von rubyw aus aufrufen müssen, wird immer weniger als eine Sekunde lang ein nerviges CMD-Fenster angezeigt.
Um dies zu vermeiden, können Sie Folgendes verwenden:
oder
In beiden Fällen wird die
ipconfig
Ausgabe gespeichertlog.txt
, es werden jedoch keine Fenster geöffnet.Sie müssen sich
require 'win32ole'
in Ihrem Skript befinden.system()
,exec()
Undspawn()
öffnet sich alles das ärgerliche Fenster , wenn TK und rubyw verwenden.quelle
Hier ist eine coole Version, die ich in einem Ruby-Skript unter OS X verwende (damit ich ein Skript starten und ein Update erhalten kann, auch nachdem ich vom Fenster weggeschaltet habe):
quelle