Pourquoi $ 1 dans une fonction n'imprime-t-il pas le premier argument du script?

13

Pourquoi echo $1n'imprime- t-il pas $1dans ce simple script bash?

#!/bin/bash
# function.sh
print_something () {
echo $1
}
print_something

$ ./function.sh 123  -> why doesn't it print '123' as a result?
pietro letti
la source
6
car vous avez oublié le $ 1 lors de l'appel de print_something. Veuillez essayer d'inclure du texte dans la question et non dans le titre.
Rui F Ribeiro
Merci. Quel devrait être l'argument écho si j'ai besoin d'insérer dans le script les commandes: print_something "$ 1"; print_something "$ 2"; et peut-être plus?
pietro letti
13
Quand j'ai vu cela à HNQ, je pensais que vous imprimiez des billets d'un dollar et espérais lire une histoire juteuse sur la façon dont votre imprimante détecte que vous imprimez de la fausse monnaie.
pipe
@pipe J'ai déjà eu ça avant, pour une raison quelconque, il refuse d'imprimer quoi que ce soit, pas seulement ceux avec les protections anti-impression.
Codingale

Réponses:

41

Les paramètres positionnels font référence aux arguments du script dans le niveau principal du script, mais aux arguments de fonction dans le corps de la fonction. Donc

print_something Something

serait en fait imprimer Something.

Si vous souhaitez passer les arguments du script à une fonction, vous devez le faire explicitement. Utilisation

print_something "$1"

pour passer le premier argument, ou

print_something "$@"

pour les passer tous, bien que la fonction dans l'exemple utilise uniquement la première.

weirdan
la source
1
Passer "$@"à print_something, tel qu'il est actuellement écrit, n'imprimerait cependant que le premier des arguments.
Kusalananda
13
Mais le but était de montrer comment passer tous les arguments, je présume. Le fait que la fonction, en l'état, n'utilise que le premier de ses arguments est un peu hors de propos.
weirdan
Eh bien, il suffit de penser qu'il est inutile de passer tous les arguments si seul le premier est utilisé.
Kusalananda
14
@allo No. "$*"serait une chaîne unique (jointe au premier caractère de $IFS) tandis que "$@"serait une liste d'éléments entre guillemets individuels.
Kusalananda
5
@Kusalananda le point de dire à quelqu'un qui veut passer les paramètres de ligne de commande à une fonction à utiliser "$@", même si dans ce cas il n'y a qu'un seul de ces paramètres, est de couvrir tous ces cas. Si l'OP décide d'ajouter un deuxième paramètre, il n'y a rien à changer dans l'invocation de la fonction. Et tous ceux qui liront cela apprendront la bonne façon de le faire pour éviter d'avoir à le refaire plus tard aussi.
Monty Harder
10

En effet, une fonction appelée obtient son propre ensemble de paramètres positionnels, indépendamment de l'ensemble parent / appelant. Essayer

print_something "$1"

(et echo "$1", ou mieux encore printf '%s\n' "$1", n'oubliez pas de citer les extensions de paramètres et qui echone peuvent pas être utilisées pour des données arbitraires).

RudiC
la source
Vous devez clarifier ce dont vous parlez. L'appelant $1est généralement différent de la fonction $1, bien qu'ils puissent devenir les mêmes s'ils sont utilisés comme proposé ci-dessus. Si je comprends bien, le echopeut rester le même ( echo $1) lorsque la fonction est appelée avec des paramètres uniques ( print_something $2prend le $ 1 de l'appelant et le "fait" $1à l'intérieur de la fonction)
RudiC
6
L'utilisation echo $1n'a de sens que si vous souhaitez $1être traité comme une liste de modèles de fichiers délimités par $ IFS à développer. echo "$1"aurait plus de sens, mais ne produirait pas le contenu de $1pour des valeurs $1similaires -nene, -EE...
Stéphane Chazelas