È possibile utilizzare le variabili dei parametri della shell ($ 1, ..., $ @) direttamente nella CLI?


9

A volte è necessario emulare e verificare le variabili sopra in piccoli esempi e quindi possono essere copiate immediatamente in alcuni script, ecc.

Ho provato a risolvere usando un semplice esempio nei seguenti modi:

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

e con altre combinazioni. Ha anche sperimentato aggiungendo la direttiva sull'interprete shebang #!/bin/sh -x, ma non ha ottenuto il risultato desiderato.

Posso farlo semplicemente?


1
(find $1) /tmpè un errore di sintassi. In realtà (any-command) more-argumentsè un errore di sintassi. Puoi spiegare diversamente cosa stai cercando di fare?
Celada,

2
@Celada, non è un errore di sintassi in gusci della rcfamiglia ( rc, es, akanga...), dove in questo caso che è equivalente a find $1 /tmp.
Stéphane Chazelas,

Risposte:


15

Il primo argomento successivo sh -c inline-scriptva a $0(che viene utilizzato anche per i messaggi di errore), e il resto va avanti $1, $2...

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

Quindi tu vuoi:

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

(ai vecchi tempi, potevi trovare shimplementazioni in cui $1invece andava il primo argomento , quindi avresti dovuto:

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

O:

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

per tenere conto di entrambi i comportamenti, ma quelle shell sono sparite ora che POSIX è prevalente e disponibile al pubblico).


Se si desidera impostare $1, $2in un ambito locale all'interno della shell corrente, è qui che si utilizzerebbero le funzioni. In gusci tipo Bourne:

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

Alcune shell supportano funzioni anonime. Questo è il caso di zsh:

(){find "$1"} /tmp

Oppure es:

@{find $1} /tmp

Per modificare gli attuali parametri posizionali, in modo permanente, la sintassi dipende dalla shell. dchirikov ha già coperto la Bourne-come gusci (Bourne, Korn, bash, zsh, POSIX, ash, yash...).

La sintassi è:

set arg1 arg2 ... argn

Tuttavia, è necessario:

set --

Per svuotare quell'elenco (o shift "$#") e

set -- -foo

impostare $1su qualcosa che inizia con -o +, quindi è una buona abitudine usare sempre set --specialmente quando si usano dati arbitrari come set -- "$@" other-argaggiungere argomenti alla fine dell'elenco dei parametri posizionali.

Nelle shell della cshfamiglia ( csh, tcsh), si assegna argvall'array:

set argv=(arg1 arg2)

In conchiglie della rcfamiglia ( rc, es, akanga), alla *matrice:

*=(arg1 arg2)

Puoi anche assegnare elementi singolarmente:

2=arg2

In fish, i parametri posizionali sono nella argvmatrice unica (senza $1, $@vi):

set argv arg1 arg2

In zsh, per compatibilità con csh, puoi anche assegnare argvall'array:

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

E puoi anche fare:

5=arg5

Ciò significa che puoi anche fare cose come:

argv+=(another-arg)

per aggiungere un argomento alla fine e:

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

per rimuovere un argomento dalla fine o dalla metà, cosa che non si può fare facilmente con altre shell.


7
set --

è quello che ti serve:

$ set -- aaa bbb ccc
$ echo "$1"
aaa
$ echo "$2"
bbb
$ echo "$3"
ccc
$ echo "$@"
aaa bbb ccc
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.