2010-11-04 13 views
11

En mi secuencia de comandos, deseo poder escribir en un archivo o en stdout en función de ciertas condiciones. Tengo curiosidad de por qué esto no funciona en mi guión:Redirección de Bash con descriptor de archivo o nombre de archivo en la variable

out=\&1 
echo "bird" 1>$out 

me trataron diferente combinación de cotizaciones, pero sigo teniendo un archivo "& 1" creado en lugar de ello por escrito a la salida estándar. ¿Qué puedo hacer para que esto funcione como yo quiero?

+0

¿Su sistema admite out =/dev/stdout? – mob

Respuesta

1

Estoy bastante seguro de que tiene que ver con el orden en que bash procesa la línea de comandos. Las siguientes obras:

export out=\&1 
eval "echo bird 1>${out}" 

debido a que la sustitución de variables sucede antes la evaluación.

0

Probar con eval. Se debe trabajar por interpretar el valor de $out sí:

out='&1' 
eval "echo \"bird\" 1>$out" 

imprimirá bird en la salida estándar (y en un archivo si cambia out).

Tenga en cuenta que debe tener cuidado con lo que va dentro de la cadena eval. Tenga en cuenta la barra diagonal inversa con las comillas internas, y que la variable $out está susbstituida (mediante las comillas dobles) antes de realizar la evaluación.

5

Una alternativa más segura, posiblemente, a eval es dup su destino en un descriptor de archivo temporal utilizando exec (descriptor de archivo 3 en este ejemplo):

if somecondition; then exec 3> destfile; else exec 3>&1; fi 

echo bird >&3 
+0

+1, es mejor evitar 'eval'. –

+3

@Dennis: Realmente no puedo entender ese cliché de evaluación ... Parece que está llenando todas las preguntas relacionadas con bash en stackoverflow :) Una y mil vez: 'eval' es una herramienta y no un riesgo en sí mismo ... Es como decir que debes evitar Lisp porque puedes considerar los datos de Lisp como código ... –

+1

@Diego: 'eval' puede ser una herramienta útil. También presenta serios riesgos potenciales de seguridad. Si lo evita, no tiene que preocuparse por ese conjunto particular de riesgos. A menudo es fácil de evitar Tome la ruta fácil y segura siempre que sea posible. Cuando use 'eval', asegúrese de que realmente lo necesita y de que desinfecta correctamente la entrada y tome los demás pasos necesarios para evitar problemas. Ver [BashFAQ/048] (http://mywiki.wooledge.org/BashFAQ/048) y [esta excelente pregunta SO] (http://stackoverflow.com/q/2571401) (a favor y en contra). Además, tenga en cuenta que dije "lo mejor es evitar", "no usar nunca". –

2

Dao y la respuesta de Diego. Para cambiar donde stdout va condicionalmente

if [ someCondition ] ; then 
    # all output now goes to $file 
    exec 1>$file 
fi 

echo "bird" 

O cree su propio descriptor de archivo;

if [ someCondition ] ; then 
    # 3 points to stdout 
    exec 3>&1 
else 
    # 3 points to a file 
    exec 3>$outfile 
fi 

echo "bird" >&3 

Adaptado de: csh programming considered harmful - Hay que ver para algunos más trucos de redirección. O lee la página del hombre bash.

+0

Estaba teniendo problemas para hacer que esto funcione en mi propio script, terminé teniendo que usar la notación de expansión variable completa por alguna razón, por ejemplo:' destfile = "/ some/path"; exec 3> $ {destfile} ' – Eliot

2

A partir de 2015, es posible redireccionar a >&${out}. Por ejemplo,

exec {out}>&1 
echo "bird" 1>&${out} 
Cuestiones relacionadas