Mit dieser -c
Option können Programme Befehle ausführen. Es ist viel einfacher zu gabeln und zu tun
execl("/bin/sh", "sh", "-c", "date | od -cb && ps > ps.out", NULL);
als es ist zu verzweigen, erstellen Sie eine Pipe, gabeln Sie erneut, rufen Sie execl
jedes untergeordnete Element auf, rufen Sie an wait
, überprüfen Sie den Exit-Status, gabeln Sie erneut, rufen Sie auf close(1)
, öffnen Sie die Datei, stellen Sie sicher, dass sie in Dateideskriptor 1 geöffnet ist, und führen Sie eine andere aus execl
. Ich glaube, dass dies der Grund war, warum die Option überhaupt geschaffen wurde.
Die system()
Bibliotheksfunktion führt einen Befehl mit der obigen Methode aus.
- Es bietet eine Möglichkeit, einen beliebig komplexen Befehl zu übernehmen und ihn wie einen einfachen Befehl aussehen zu lassen. Dies ist nützlich bei Programmen, die einen benutzerdefinierten Befehl ausführen, z. B.
find … -exec
oder xargs
. Aber das wusstest du schon; Es war Teil der Antwort auf Ihre Frage:
Wie kann ein zusammengesetzter Befehl als Argument für einen anderen Befehl angegeben werden?
Dies kann nützlich sein, wenn Sie eine andere interaktive Shell als Bash ausführen. Umgekehrt können Sie diese Syntax verwenden, wenn Sie bash ausführen
$ ash -c " Befehl "
︙
$ csh -c " Befehl "
︙
$ dash -c " Befehl "
︙
$ zsh -c " Befehl "
︙
einen Befehl in einer anderen Shell ausführen, da alle diese Shells auch die -c
Option erkennen. Natürlich könnten Sie mit das gleiche Ergebnis erzielen
$ Asche
ash $ Befehl
︙
Asche $ Ausgang
$ cshBefehl
csh $
︙
csh $ exit
$ dash
Dash $ Befehl
︙
dash $ exit
$ zshBefehl
zsh $
︙
zsh $ exit
Ich habe ash$
usw. verwendet, um die Eingabeaufforderungen der verschiedenen Muscheln zu veranschaulichen. Sie würden diese wahrscheinlich nicht wirklich bekommen.
Dies kann nützlich sein, wenn Sie einen Befehl in einer "frischen" Bash-Shell ausführen möchten. zum Beispiel,
$ ls -lA
total 0
-rw-r--r-- 1 gman gman 0 Apr 14 20:16 .file1
-rw-r--r-- 1 gman gman 0 Apr 14 20:16 file2
$ echo *
file2
$ shopt -s dotglob
$ echo *
.file1 file2
$ bash -c "echo *"
file2
oder
$ type shift
shift is a shell builtin
$ alias shift=date
$ type shift
shift is aliased to ‘date’
$ bash -c "type shift"
shift is a shell builtin
Das Obige ist eine irreführende Übervereinfachung. Wenn bash mit ausgeführt wird -c
, wird es als nicht interaktive Shell betrachtet und nicht gelesen ~/.bashrc
, sofern nicht anders -i
angegeben. Damit,
$ Typ cp
cp ist auf 'cp -i' # aliasiert. Definiert in ~ / .bashrc
$ cp .file1 file2
cp: 'file2' überschreiben? n
$ bash -c "cp .file1 file2"
# Bestehende Datei wird ohne Bestätigung überschrieben!
$ bash -c -i "cp .file1 file2"
cp: 'file2' überschreiben? n
Sie könnten verwenden -ci
, -i -c
oder -ic
statt -c -i
.
Dies gilt wahrscheinlich in gewissem Maße für die anderen in Absatz 3 genannten Shells, sodass die Langform (dh die zweite Form, bei der es sich tatsächlich um genau die gleiche Menge an Eingabe handelt) möglicherweise sicherer ist, insbesondere wenn Sie Initialisierungs- / Konfigurationsdateien eingerichtet haben für diese Muscheln.
Wie Wildcard erklärt hat, können Änderungen an der in der Subshell vorgenommenen Umgebung keine Auswirkungen auf die übergeordnete Shell (aktuelles Verzeichnis, Umgebungswerte) haben , da Sie einen neuen Prozessbaum (einen neuen Shell-Prozess und möglicherweise dessen untergeordnete Prozesse) ausführen
Variablen, Funktionsdefinitionen usw.) Daher ist es schwer vorstellbar, dass ein Shell-Befehl eingebaut ist, der nützlich wäre, wenn er von ausgeführt wird sh -c
.
,, und kann Hintergrundjobs, die von der übergeordneten Shell gestartet fg
wurden bg
, jobs
nicht beeinflussen oder darauf zugreifen oder auf wait
sie warten.
Dies entspricht im Wesentlichen dem normalen Ausführen direkt von der interaktiven Shell aus.
ist eine große Zeitverschwendung.
undsh -c "exec some_program"
some_program
sh -c exit
ulimit
umask
könnte die Systemeinstellungen für den untergeordneten Prozess ändern und dann beenden, ohne sie auszuüben.
Fast der einzige eingebaute Befehl, der in einem sh -c
Kontext funktionsfähig wäre, ist kill
. Natürlich, dass die Befehle nur erzeugen Ausgang ( echo
, printf
, pwd
und type
) nicht betroffen ist, und, wenn Sie eine Datei schreiben, wird das bestehen bleiben.
- Natürlich können Sie ein eingebautes in Verbindung mit
einem externen Befehl verwenden. z.B,
sh -c "cd some_directory ; some_program "
Mit einer normalen Unterschale können Sie jedoch im Wesentlichen den gleichen Effekt erzielen:
(cd some_directory ; some_program )
das ist effizienter. Das gleiche (beide Teile) kann für so etwas gesagt werden
sh -c "umask 77; some_program "
oder ulimit
(oder shopt
). Und da Sie -c
nach der Komplexität eines vollständigen Shell-Skripts einen beliebig komplexen Befehl eingeben können, haben Sie möglicherweise Gelegenheit, das Repertoire der integrierten Funktionen zu verwenden. zB source
, read
, export
, times
, set
und unset
, usw.
echo printf type pwd
sind eingebaute; so sindset shopt shift read readarray mapfile trap declare/typeset export local let readonly unset
die in einem mäßig kompliziert nützlich sein , noch nicht die Eltern beeinflussen , sondern kann-c
.