Praktische Verwendung der Option `set -k` in bash

16

Wann verwenden wir set -kOption in Bash?

Bash Referenzhandbuch sagt,

Alle Argumente in Form von Zuweisungsanweisungen werden für einen Befehl in die Umgebung gestellt, nicht nur diejenigen, die vor dem Befehlsnamen stehen.

Ich verstehe, was die Option tut, konnte mir aber nicht vorstellen, wann wir sie brauchen.

MS.Kim
quelle
Richtige Wahrnehmung. Dadurch -kkönnen wir 30 Jahre alte Shell-Skripte ausführen, ohne sie umgestalten zu müssen. Übergeben Sie temporäre Umgebungsvariablen stattdessen mithilfe der Präfixsyntax:var1=x var2=y command ...
Henk Langeveld,

Antworten:

14

Sie können es grundsätzlich immer dann verwenden, wenn Sie die an ein Shell-Skript übergebenen Umgebungsvariablen (als Argumente) "einfügen" möchten, als ob sie in der Umgebung über festgelegt exportwären, ohne dass sie exportvor dem Ausführen von Befehlen permanent in der Liste gespeichert sein müssen .

HINWEIS: Es gibt auch die lange Form des -kSchalters set -o keyword.

Beispiel

$ cat cmd1.bash 
#!/bin/bash

echo $VARCMD

Nun, wenn ich set -k:

$ set -k; ./cmd1.bash VARCMD="hi"; set +k
hi

Aber wenn ich nur das obige Skript ausführen würde:

$ ./cmd1.bash 

$

Was macht der Export?

$ help export
...
Marks each NAME for automatic export to the environment of subsequently
executed commands.  If VALUE is supplied, assign VALUE before exporting.
...

Wenn wir also so etwas export | grep VARzu unserem Skript hinzufügen würden :

$ cat cmd2.bash 
#!/bin/bash

echo $VARCMD
export | grep VAR

Und wir haben unsere obigen Tests erneut durchgeführt:

$ set -k; ./cmd2.bash VARCMD="hi"; set +k
hi
declare -x VARCMD="hi"

Aber ohne set -k:

$ ./cmd2.bash 

$

Dies set -kermöglicht uns, Variablen vorübergehend in Masse zu exportieren.

Ein anderes Beispiel

$ cat cmd3.bash 
#!/bin/bash

echo $VARCMD1
echo $VARCMD2
export | grep VAR

Wenn wir mehrere Variablen setzen, werden sie alle exportiert:

$ set -k; ./cmd3.bash VARCMD1="hi" VARCMD2="bye"; set +k
hi
bye
declare -x VARCMD1="hi"
declare -x VARCMD2="bye"

Dann werden also nur alle Umgebungsvariablen injiziert?

Nein -kmacht hier eine sehr explizite Sache. Es werden nur Variablen exportiert, die in der Befehlszeile enthalten waren, als ein Befehl ausgeführt wurde.

Beispiel

Sagen wir, ich setze diese Variable:

$ VARCMD1="hi"

Wenn wir jetzt den gleichen Befehl ausführen, lassen wir Folgendes aus VARCMD1="hi":

$  set -k; ./cmd3.bash VARCMD2="bye"; set +k

bye
declare -x VARCMD2="bye"

Aber warum gibt es das?

Ich habe diese Quelle gefunden, die ein wenig über diese Funktion mit dem Titel "Keyword Parameter Assignment Strings" erklärt. HINWEIS: Die Quell-URL verwendet eine IP-Adresse, sodass ich hier auf SE keine direkte Verknüpfung herstellen kann.

http://140.120.7.21/OpenSystem2/SoftwareTools/node16.html

Bei der Programmierung in einer beliebigen Sprache sind die Variable und ihre Wertübergabe für das Schreiben zuverlässigen Codes von entscheidender Bedeutung. Neben den Variablentypen Integer und Array akzeptieren alle anderen Shell-Variablen Zeichenfolgen als ihre Werte. Wenn wir über die Shell-Programmiersprache sprechen, bevorzugen wir aus Gründen der Konsistenz den Ausdruck "Schlüsselwortparameter". Beachten Sie beim Zuweisen von Werten zu Schlüsselwortparametern die folgenden Punkte:

  • Um unerwartete Auswirkungen zu vermeiden, platzieren Sie den Parameterzuweisungs-Teilstring immer vor einer Befehlszeichenfolge.

    In der B-Shell werden die zugewiesenen Werte der Schlüsselwortparameter in (lokalen) Shell-Variablen gespeichert. In bash und ksh werden die dem Befehl vorangehenden Schlüsselwort-Parameterzuweisungszeichenfolgen nicht in den Shell-Variablen gespeichert. Sie wirken sich nur auf den unmittelbaren Unterprozess aus, der zur Ausführung des aktuellen Befehls aufgerufen wurde. Nur eine Zeile mit Zuweisungszeichenfolgen für Schlüsselwortparameter wird in den (lokalen) Shell-Variablen gespeichert. Zeichenfolgen für die Zuweisung von Schlüsselwortparametern können auch als Argumente für die Befehle alias, declare, typeset, export, readonly und local builtin angezeigt werden. [Abschnitt 3.4 des Bash-Referenzhandbuchs]

  • Die Schlüsselwortparameterzuweisungszeichenfolgen werden als Argumente für den auszuführenden Befehl behandelt, wenn sie hinter dem Befehlsnamen stehen.

  • Die Schlüsselwortparameter können mit dem Befehl set bearbeitet werden.
slm
quelle
In diesem Link, ss64.com/bash/set.html , set -khaben sie dazu -o keyworddie -kOption angegeben. Bedeutet das etwas?
Ramesh
@Ramesh - set -o keywordist die Langform von set -k. Sehen help set | grep -- '-k'.
SLM
ach ok Ich habe mich lange am Kopf gekratzt und versucht zu verstehen, warum es zwei Möglichkeiten gibt. Wie immer perfekte Antwort :)
Ramesh
4
./cmd.bash VARCMD=himuss set -kdafür sorgen , dass es genau so VARCMD=hi ./cmd.bashfunktioniert, wie es ohne das geht set -k. Schätze, die spezielle Frage des OP ./cmd.bash VARCMD=hi
betrifft
@ 1_CR - guter Punkt. Ich glaube, es hat vor allem mit Stil zu tun, aber ich werde sehen, ob ich eine tatsächliche Quelle finden kann.
SLM
8

Jede praktische Verwendung von set -kist wahrscheinlich nur persönlicher Stil. Einige - vielleicht diejenigen, die Programmiersprachen mögen, die die Möglichkeit bieten, Schlüsselwortargumente in Funktionsaufrufen zu verwenden, oder jene wenigen, die dddie Syntax des Befehls mögen - bevorzugen

set -k
...
Befehl var 1 = val 1 var 2 = val 2

zu

var 1 = Wert 1 var 2 = Wert 2 Befehl

Der eigentliche Grund, warum die Option in einigen Shells vorhanden ist, wird in der Begründung für den Befehl set im POSIX-Standard erläutert :

The following set flags were omitted intentionally with the following rationale:

The -k flag was originally added by the author of the Bourne shell to make it easier
for users of pre-release versions of the shell. In early versions of the Bourne shell
the construct
    set name=value
had to be used to assign values to shell variables.
Mark Plotnick
quelle