Est-il possible d'utiliser des variables de paramètres shell ($ 1,…, $ @) directement dans CLI?


9

Parfois, il est nécessaire d'émuler et de vérifier les variables ci-dessus dans de petits exemples, puis de les copier immédiatement dans un script, etc.

J'ai essayé de résoudre en utilisant un exemple simple de la manière suivante:

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

et avec d'autres combinaisons. Expérimenté également en ajoutant la directive d'interprétation shebang #!/bin/sh -x, mais n'a pas obtenu le résultat souhaité.

Puis-je faire cela simplement?


1
(find $1) /tmpest une erreur de syntaxe. (any-command) more-argumentsEst en fait une erreur de syntaxe. Pouvez-vous expliquer différemment ce que vous essayez de faire?
Celada

2
@Celada, ce n'est pas une erreur de syntaxe dans des coquilles de la rcfamille ( rc, es, akanga...), où dans ce cas , qui est équivalent à find $1 /tmp.
Stéphane Chazelas

Réponses:


15

Le premier argument après sh -c inline-scriptva à $0(qui est également utilisé pour les messages d'erreur), et le reste entre $1, $2...

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

Alors tu veux:

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

(dans les temps anciens, vous pouviez trouver des shimplémentations où le premier argument est entré à la $1place, vous feriez donc:

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

Ou:

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

pour tenir compte des deux comportements, mais ces coquilles ont disparu maintenant que POSIX est répandu et accessible au public).


Si vous souhaitez définir $1, $2dans une portée locale dans le shell actuel, c'est là que vous utiliserez les fonctions. En coquilles de type Bourne:

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

Certains shells prennent en charge les fonctions anonymes. C'est le cas de zsh:

(){find "$1"} /tmp

Ou es:

@{find $1} /tmp

Pour modifier définitivement les paramètres de position actuels, la syntaxe dépend du shell. dchirikov a déjà couvert la Bourne comme des coquilles (Bourne, Korn, bash, zsh, Posix ash, yash...).

La syntaxe est:

set arg1 arg2 ... argn

Cependant, vous avez besoin de:

set --

Pour vider cette liste (ou shift "$#") et

set -- -foo

pour définir $1quelque chose commençant par -ou +, c'est donc une bonne habitude de toujours l'utiliser, en set --particulier lorsque vous utilisez des données arbitraires, comme set -- "$@" other-argpour ajouter des arguments à la fin de la liste des paramètres positionnels.

Dans les shells de la cshfamille ( csh, tcsh), vous affectez au argvtableau:

set argv=(arg1 arg2)

Dans les coquilles de la rcfamille ( rc, es, akanga), au *tableau:

*=(arg1 arg2)

Bien que vous puissiez également affecter des éléments individuellement:

2=arg2

Dans fish, les paramètres positionnels sont dans le argvtableau uniquement (non $1, $@là):

set argv arg1 arg2

Dans zsh, pour des raisons de compatibilité avec csh, vous pouvez également affecter au argvtableau:

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

Et vous pouvez aussi faire:

5=arg5

Cela signifie que vous pouvez également faire des choses comme:

argv+=(another-arg)

pour ajouter un argument à la fin, et:

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

pour supprimer un argument de la fin ou du milieu, ce que vous ne pouvez pas faire facilement avec d'autres shells.


7
set --

est ce dont vous avez besoin:

$ set -- aaa bbb ccc
$ echo "$1"
aaa
$ echo "$2"
bbb
$ echo "$3"
ccc
$ echo "$@"
aaa bbb ccc
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.