Existe-t-il un moyen de rediriger stdout et stderr via une variable comme l'ajout d'options de commande dans le script?
Par exemple, j'ai un script:
#!/bin/bash -x
TEST=">/dev/null 2>&1"
OPT='-p -v'
mkdir $OPT 123/123/123 $TEST
Je peux voir que OPT est remplacé par -p
sans aucun problème et bash l'interprète en option. Mais la redirection interprète comme nom de répertoire.
$ ./test.sh
+ TEST='>/dev/null 2>&1'
+ OPT='-p -v'
+ mkdir -p -v 123/123/123 '>/dev/null' '2>&1'
mkdir: created directory `123/123'
mkdir: created directory `123/123/123'
mkdir: created directory `>/dev'
mkdir: created directory `>/dev/null'
mkdir: created directory `2>&1'
Existe-t-il un moyen de dire bash, que $ VAR est une redirection, pas un nom de répertoire.
PS. Je me trompe peut-être, mais je veux faire une sortie verbeuse ou non verbeuse facultative à partir de mon script. Mais j'ai besoin d'une sortie même en mode non verbeux, donc je ne peux pas simplement rediriger stdout et stderr entiers, uniquement à partir de certaines commandes à l'intérieur de mon script.
la source
Le «comment» a été bien expliqué dans d'autres réponses; Je veux aborder le «pourquoi» le code de l'OP ne fonctionne pas.
La note clé est que les redirections de sortie sont marquées avant l' expansion des variables. Les redirections sont en fait effectuées après l'expansion des variables (d'où la raison pour laquelle vous pouvez rediriger la sortie vers un nom de fichier qui est stocké dans une variable), mais le shell identifie les redirections pour un traitement ultérieur avant que les variables ne soient développées.
En d'autres termes, une fois que les variables sont développées, il est "trop tard" pour qu'un caractère de redirection (
<
ou>
, etc.) soit pris en compte, car le shell a déjà identifié les parties de la chaîne de commande qu'il va gérer comme redirections.Pour plus d'informations, consultez les étapes 1 et 3 répertoriées sous:
la source
Il ne l'interprète pas comme un "nom de répertoire",
>
est cité, donc il est traité littéralement (plus précisément, vous envoyez la chaîne>dev/null 2>&1
. Votre seul moyen de contourner cela est d'utilisereval
ou de générer un nouveau shell.Quant à votre problème "verbeux" évoqué dans votre question, faites-le plutôt à la place:
la source
Vous avez beaucoup d'espaces dans vos variables, qui ne seront pas évalués correctement. Vous voudrez utiliser
eval
pour configurer cela.Cela permettra à $ OPT d'être divisé en deux arguments (
-p
et-v
) au lieu d'un (-p -v
) et le même avec $ TEST. Également modifié pour utiliser/dev/null
car il est très peu probable que vous ayez undev
répertoire dans le répertoire actuel.la source
La réponse d'Enzotib utilise une bonne magie de descripteur de fichier, mais une solution plus simple serait d'utiliser simplement
eval
la ligne (ce qui ajoute cependant une surcharge de processus):la source