Ist es möglich, Shell-Parametervariablen ($ 1,…, $ @) direkt in der CLI zu verwenden?

9

Manchmal ist es notwendig, die obigen Variablen in kleinen Beispielen zu emulieren und zu überprüfen und kann dann sofort in ein Skript usw. kopiert werden.

Ich habe versucht, anhand eines einfachen Beispiels Folgendes zu lösen:

(find $1) /tmp
sh -c '(find $1) /tmp'
sh -c "find $1" /tmp
echo '(find $1) /tmp' | sh

und mit anderen Kombinationen. Experimentierte auch durch Hinzufügen der Shebang-Interpreter-Direktive #!/bin/sh -x, erzielte jedoch nicht das gewünschte Ergebnis.

Kann ich das einfach machen?

Apostel
quelle
1
(find $1) /tmpist ein Syntaxfehler. Eigentlich (any-command) more-argumentsist ein Syntaxfehler. Können Sie anders erklären, was Sie versuchen zu tun?
Celada
2
@Celada, es ist kein Syntaxfehler in Schalen der rcFamilie ( rc, es, akanga...), wobei in diesem Fall, die äquivalent ist find $1 /tmp.
Stéphane Chazelas

Antworten:

15

Das erste Argument danach sh -c inline-scriptgeht an $0(das auch für Fehlermeldungen verwendet wird), und der Rest geht hinein $1, $2...

$ sh -c 'blah; echo "$0"; echo "$1"' my-inline-script arg
my-inline-script: blah: command not found
my-inline-script
arg

Also du möchtest:

sh -c 'find "$1"' sh /tmp

(In den alten Tagen konnten Sie shImplementierungen finden , in die $1stattdessen das erste Argument einging , also würden Sie Folgendes tun:

sh -c 'find "$1"' /tmp /tmp

Oder:

sh -c 'shift "$2"; find "$@"' sh 3 2 /tmp1 /tmp2

um beide Verhaltensweisen zu berücksichtigen, aber diese Shells sind jetzt verschwunden, da POSIX weit verbreitet und öffentlich verfügbar ist.


Wenn Sie festlegen mögen $1, $2in einem lokalen Bereich innerhalb des aktuell Shell, das ist , wo Sie Funktionen verwenden würden. In Bourne-ähnlichen Muscheln:

my_func() {
  find "$1"
}
my_func /tmp

Einige Shells unterstützen anonyme Funktionen. Das ist der Fall von zsh:

(){find "$1"} /tmp

Oder es:

@{find $1} /tmp

Um die aktuellen Positionsparameter dauerhaft zu ändern, ist die Syntax von der Shell abhängig. dchirikov hat bereits die Bourne-wie Muscheln bedeckt (Bourne, Korn, bash, zsh, POSIX, ash, yash...).

Die Syntax lautet:

set arg1 arg2 ... argn

Sie benötigen jedoch:

set --

Um diese Liste (oder shift "$#") zu leeren und

set -- -foo

In dem Satz $1zu etwas ab -oder +, es ist so immer eine gute Gewohnheit verwendet set --vor allem , wenn beliebige Daten wie die Verwendung von set -- "$@" other-argArgumenten an das Ende der Positionsparameterliste hinzuzufügen.

In Shells der cshFamilie ( csh, tcsh) weisen Sie dem argvArray Folgendes zu:

set argv=(arg1 arg2)

In Schalen der rcFamilie ( rc, es, akanga), an das *Array:

*=(arg1 arg2)

Sie können Elemente aber auch einzeln zuweisen:

2=arg2

In fishsind die Positionsparameter in dem argvArray nur (keine $1, $@dort):

set argv arg1 arg2

Aus zshKompatibilitätsgründen cshkönnen Sie dem argvArray auch Folgendes zuweisen :

argv=(arg1 arg2)
argv[4]=arg4

Und Sie können auch tun:

5=arg5

Das heißt, Sie können auch Dinge tun wie:

argv+=(another-arg)

um am Ende ein Argument hinzuzufügen, und:

argv[-1]=()
argv[2]=()

um ein Argument vom Ende oder der Mitte zu entfernen, was mit anderen Shells nicht einfach ist.

Stéphane Chazelas
quelle
7
set --

ist was du brauchst:

$ set -- aaa bbb ccc
$ echo "$1"
aaa
$ echo "$2"
bbb
$ echo "$3"
ccc
$ echo "$@"
aaa bbb ccc
dchirikov
quelle