He intentado encontrar una respuesta a esta pregunta, pero no tengo suerte hasta ahora:
Tengo un script que se ejecuta algunos otros scripts, y muchos de esos otros scripts tienen "conjunto -x" en ellos, lo que hace que se imprimen todos los comandos se ejecutan. Me gustaría deshacerse de eso, pero retener la información si alguna de las secuencias de comandos enviar el mensaje de error en stderr.
Así que no puedo escribir simplemente ./script 2>/dev/null
Además, no tengo privilegios para editar los otros scripts, así que no puedo cambiar manualmente la opción set.
Estaba pensando en el registro de todo, desde stderr al archivo separado y filtrado de los comandos de rastreo, pero tal vez hay una manera más sencilla?
./script 2>some_file
Respuestas:
Con
bash
4.1 y superior, puedes hacer(también funciona cuando
bash
se invoca comosh
).Básicamente, le estamos diciendo
bash
a la salida de laxtrace
salida en el descriptor de archivo de 7 en lugar del predeterminado de 2, y la redirección que descriptor de archivo a/dev/null
. El número fd es arbitrario. Use un fd superior a 2 que no se use de otra manera en su secuencia de comandos. Si la envoltura que está entrando en este comando esbash
oyash
, incluso se puede utilizar un número superior a 9 (aunque es posible que encuentre problemas si el descriptor de archivo es usado internamente por la cáscara).Si la envoltura que está llamando que
bash
la escritura es dezsh
, también se puede hacer:para que la variable se asigne automáticamente el primer fd libre por encima de 9.
Para versiones anteriores de
bash
, otra opción, sixtrace
se activa conset -x
(en lugar de#! /bin/bash -x
oset -o xtrace
) sería redefinirset
como una función exportada que no hace nada cuando se pasa-x
(aunque eso rompería el script si (o cualquier otrobash
script que invoque) utilizadoset
para establecer los parámetros posicionales).Me gusta:
Otra opción es agregar una trampa DEPURACIÓN en un
$BASH_ENV
archivo que lo haceset +x
antes de cada comando.Sin
set -x
embargo, eso no funcionará cuando se haga en un sub-shell.Como @ilkkachu Dicho esto, siempre y cuando tenga permiso de escritura en cualquier carpeta del sistema de archivos, por lo menos debe ser capaz de hacer una copia del guión y editarlo.
Si no hay ningún lugar donde pueda escribir una copia del guión, o si no es conveniente hacer y editar una nueva copia cada vez que hay una actualización del guión original, aún puede hacer:
Eso (y el enfoque de copia) puede no funcionar correctamente si el script hace algo elegante
$0
o con variables especiales como$BASH_SOURCE
(como buscar archivos que estén relacionados con la ubicación del script en sí), por lo que es posible que deba editar un poco más, como reemplazar$0
con la ruta del script ...fuente
{BASH_XTRACEFD}>
truco también funciona enbash
4.1 o posterior.ksh93
obash
en la que la variable no se pasa en el entorno del comando (compárese<shell> -c 'export fd; printenv fd {fd}> /dev/null'
enzsh
,bash
yksh93
). Se podría hacer que funcione enksh93
/bash
por hacerlo en dos pasos o posiblemente usandoeval
, pero parabash
, que tienen efectos secundarios si la opción xtrace estaba en marcha.Ya que son secuencias de comandos, podría hacer copias de ellos, y editar los.
Aparte de eso, filtrar la salida parecería simple, podría establecer explícitamente
PS4
algo más inusual que una sola ventaja, para facilitar el filtrado:(por supuesto, eso colapsará stdout y stdin, pero las tuberías solo stderr en Bash se vuelven un poco peludas, así que lo ignoraré)
fuente
PS4="%%%%" bash script.sh 2> >(grep -ve '^%%%%')
.bash
cuenta cuestiones como quegrep
se ejecuta de forma asíncrona (bash no está esperando por ella, por lo que puede (ya menudo lo hace) cosas salida después de que el siguiente comando en la secuencia de comandos se inicia).