Votre shell interprète les guillemets, à la fois '
et "
, avant même qu'ils ne parviennent à echo
. Je mets généralement des guillemets autour de mon argument pour faire écho même s'ils ne sont pas nécessaires; par exemple:
$ echo "Hello world"
Hello world
Ainsi, dans votre premier exemple, si vous souhaitez inclure des guillemets littéraux dans votre sortie, vous devez soit les échapper:
$ echo \'Hello world\'
'Hello world'
Ou ils doivent déjà être utilisés dans un argument cité (mais ce ne peut pas être le même type de citation, ou vous devrez quand même y échapper):
$ echo "'Hello world'"
'Hello world'
$ echo '"Hello world"'
"Hello world"
Dans votre deuxième exemple, vous exécutez une substitution de commande au milieu de la chaîne:
grep $ARG /var/tmp/setfile | awk {print $2}
Les choses qui commencent par $
sont également gérées spécialement par le shell - il les traite comme des variables et les remplace par leurs valeurs. Étant donné que très probablement aucune de ces variables n'est définie dans votre shell, il s'exécute simplement
grep /var/tmp/setfile | awk {print}
Étant donné qu'il grep
ne voit qu'un seul argument, il suppose que cet argument est le modèle que vous recherchez et que l'endroit où il doit lire les données est stdin, il bloque donc l'attente de l'entrée. C'est pourquoi votre deuxième commande semble se bloquer.
Cela ne se produira pas si vous citez l'argument (ce qui explique pourquoi votre premier exemple a presque fonctionné), c'est donc une façon d'obtenir la sortie souhaitée:
echo \'' echo PARAM=` grep $ARG /var/tmp/setfile | awk '{print $2}' ` '\'
Vous pouvez également le mettre entre guillemets, mais vous devrez ensuite échapper le $
s pour que le shell ne les résout pas en tant que variables, et les astuces pour que le shell n'exécute pas immédiatement la substitution de commande:
echo "' echo PARAM=\` grep \$ARG /var/tmp/setfile | awk '{print \$2}' \` '"